Newsgroup: it.comp.lang.c++
Titolo: passaggio riferimento a valori temporanei

#include <stdlib>
#include <string>
#include <iostream>
using namespace std;
void Stampa(string &S)
{
 cout << S << endl;
}
int main()
{
 Stampa("Caso 1");
 char *a="Caso 2";
 Stampa(a);
 string b("Caso 3");
 Stampa(b);
 system("PAUSE");
 return 0;
}
//****************
Le prime due stampe danno un warning (la terza è il modo corretto di passare
la stringa, spero) a proposito del passaggio di un riferimento ad un valore
temporaneo. Suppongo che nel primo caso il compilatore crei una string e poi
ne passi il riferimento alla funzione, ma non ho capito quando questa
stringa temporanea verrà distrutta.
Può essere pericoloso usare gli oggetti temporanei in questo modo? (se no
non vedo perchè il compilatore mi dovrebbe avvisare) Il caso 2 corrisponde
al caso 1? Cioè il compilatore ha creato una string temporanea creata dal
puntatore char?
Grazie

 puntatore char?
Il caso in esame non dovrebbe comportare problematiche.
Il pericolo consiste se si continua a mantenere riferimenti o puntatori alla
variabile in questione. Ad esempio:
string& Stampa(string& S)
{
 cout << S << endl;
    return S;
}
int main()
{
     string& res = Stampa("Caso 1");
    char stringa2[1024] = "Caso 2";
    Stampa(stringa2);
    Stampa(res);
    return 0;
}
Siamo riusciti a mantenere il riferimento ad una variabile temporanea
probabilmente distrutta da tempo.
Ciao,
Giambattista

 puntatore char?
Prima di tutto il compilatore ti da' un warning perche' quello che hai
fatto nei primi due esempi e' illegale in C++ (a mio avviso dovrebbe
darti un errore e non un warning, ma alla Borland la pensano
diversamente).
Il pericolo comunque non sta nella costruzione di un oggetto temporaneo,
che viene comunque distrutto alla fine dell'espressione completa che lo
utilizza, quindi dopo che la tua funzione Stampa() e' ritornata; questo
meccanismo e' perfettamente valido se tu passi i parametri per reference
a const: prova a definire Stampa come
void Stampa(const string & S);
Il pericolo e' che si possono introdurre bachi subdoli e difficili da
individuare. Ad esempio:
void f(int & i) {
  ++i;
}
int main() {
  double d = 2.3;
  f(d);
 }
Ti aspetti di incrementare d ed invece viene creato un temporaneo di
tipo int che viene incrementato e subito distrutto.
Ciao,
Nicola

 ha scritto nel
messaggio news:3C765AA3...@divalsim.it...

Posto che l'overloading esiste apposta, personalmente non
ritengo che i due esempi siano illegali: dei costruttori di
copia che hanno un parametro in ingresso diverso dalla
classe che creano si parla, appunto, come di conversioni
implicite definite dall'utente. Se il costruttore
class String{ //so che in <string> non c'è esattamente
questo, ma semplifico per l'esempio
  String(const char * source);//conversione stringa C->
stringa C++
}
fosse explicit:
class String{
  explicit String(const char * source);//conversione stringa
C-> stringa C++
}
allora avresti ragione tu, ma non essendo così, l'esempio è
perfettamente legale. Per verificare, si può abilitare la
compilazione ANSI rigorosa(non è un termine preciso, l'ho
sparato al momento), cioè che rifiuta estensioni
proprietarie al linguaggio.
Spero di essere stato utile.
Ciao
--
Paolo Giarrusso

 implicite definite dall'utente.
I due esempi sono illegali. Nicola non stava perlando della conversione
implicita.
Negli esempi in questione il compilatore di BauD instanzia un temporaneo
std::string e lo passa alla funzione Stampa(), il cui parametro è un
reference NON-const. Ora, il binding di un reference non-const a un
temporaneo non è consentito dallo standard. Tuttavia, alcuni compilatori lo
permettono, emettendo comunque un warning (il gcc, almeno fino a una certa
versione, e il Borland, stando a quando dice Nicola).
Max

 ritengo che i due esempi siano illegali: 
non e` questione di opinioni e pareri personali, ma di regole dello 
standard. Lo standard dice esplicitamente che un temporaneo puo` essere 
legato solo a riferimenti const; quindi codice del genere e` illegale:
void foo(double&);
void bar()
{
        int i;
        foo(i); // errore
}
dato che il temporaneo ottenuto dalla conversione int->double dovrebbe 
essere legato ad un reference non-const.
ciao Anto
-- 
Antonio Cuni, 19 anni, studente
Brainbench C++ Master: 4.73, higher than 99% of all previous test takers.
C Language: 3.79, higher than 92% of all previous test takers.
Guida C/C++ di Programmazione.it: 
http://cpp.programmazione.it