Newsgroup: it.comp.lang.c++
Titolo: reference e variabili temporanee

ciao a tutti
ho un dubbio :
int a=10;
float &b = a;
in questo caso il reference b viene inizializzato con l'indirizzo di una
variabile float temporanea, a sua volta inizializzata dal un int.
la domanda è : ma le variabili temporanee non dovrebbero essere const?
perchè il compilatore (ho provato sia borland c++ builder che g++) mi
permette di assegnare l'indirizzo di un const ad un non-const reference?
non è pericoloso modificare tramite b il valore di un indirizzo di un file
temporaneo (che quindi alla fine dell'istruzione non esiste piu') ?
grazie
franz

 la domanda è : ma le variabili temporanee non dovrebbero essere const?
Vero. Per evitare di cambiare un valore temporaneo. Quindi ad esempio puoi
fare:
const int& a = int(10);
ma non
int& a = int(10);
perchè avresti un reference non-const ad una variabile temporanea.
Alla stessa maniera puoi fare
const int& a = 1;
e non
int& a =1;
Un altra cosa interessante è che la variabile temporanea a cui fa riferimento
un reference, prende come lifetime quello del reference. Ad esempio supponi di
avere una funzione dichiarata così:
int f();
tu potresti scrivere una cosa del tipo:
const int& a = f(); (ma non int& a = f())
la funzione f ritorna però una variabile temporanea che solitamente verrebbe
distrutta al termine della riga. Se però questa variabile viene utilizzata per
utilizzare un reference, verrà distrutta solamente dopo che è stato distrutto
il reference.
Ciao Fulvio.

 Ciao Fulvio.
ciao
Franz

 avvisandomi soltanto che b punta ad un oggetto temporaneo..
Interessante. Utilizza una conversione standard per trasformare l'int in un
float, crea un temporaneo e poi utilizza lo stesso per inizializzare il
reference. Sicuramente non dovrebbe lasciarti inizializzare un reference
non-const con un oggetto temporaneo, perņ...
Perņ mi viene da pensare che con il const ha ragione lui, cioč se io faccio:
int a = 10;
const float& b = float(a);
č perfettamente legale, e la variabile temporanea (a) esiste per tutta la vita
di b.
Di conseguenza, visto che la conversione da int a float č implicita (posso
scrivere float f  = int (10); ) č anche corretto scrivere:
int a = 10;
const float& b = a;
Ciao Fbf.

 la domanda è : ma le variabili temporanee non dovrebbero essere const?
No, pero' e' vietato inizilizzare un non-const reference
con un temporaneo.
Infatti il gcc 2.95.2 da errore:
  prova1.c:3: initializing non-const `float &' with `int' will use a temporary
	Mauro

 Mauro
ciao
Franz

 Ciao Fbf.
ciao
Franz

float &b=10;
Stai cercando di inizializzare un riferimento (per giunta non const)
con un non l-value;
Paolo

 Paolo
ciao
Franz

rispostomi).
Non c'e` temporaneo alcuno... e se c'e` mi risulta non essere
standard compliant!
Ciao,
Paolo

 
Dunque, gcc ti avverte con un warning se cerchi di fare quel giochino con
un reference non const, mentre non dice nulla se si tratta di un reference
const. Non so se lo standard richieda che la compilazione fallisca, ma
gcc adotta questo approccio anche per altre palesi violazioni delle
regole, come passare T& dove è richiesto un const T&.
Il problema mi pare correlato alla questione della const-ness dei
temporanei, che credo sia stata discussa qui un po' di tempo fa. Io
personalmente non ho ancora capito se lo standard richieda che un
temporaneo sia da considerarsi const.
gcc, ad esempio, compila senza warning questo:
  ( std::string("ciao") = "pippo" ).resize(12);
E' giusto che ti lasci fare una cosa del genere, o no?
Max

 sappia).
Per essere standard compilant e' sufficiente che il compilatore
dica che il programma non va bene.  Lo stndard non dice niente 
sulla qualita' dei messaggi di errore e su quello che deve fare
il compiatore dopo aver segnalato l'errore.
	Mauro

 in entrambe quest'ultime il reference punta ad un temporaneo
Solo il caso con il const e' ammesso, gli altri due sono vietati.
Un non-const reference deve essere inizializzato con un lvalue
dello stesso tipo.
Un const reference puo' essere inizializzato anche con un non-lvalue
o con un altro tipo (purche' esista l conversione).  In questi casi:
- viene applicata la conversione implicita (se necessaria)
- il risultato viene messo in una variabile temporanea
- il reference viene inizializzato con il temporaneo.
Il temporaneo dura per tutta la vita del reference.
	Mauro

 E' giusto che ti lasci fare una cosa del genere, o no?
Si, std::string::operator= restituisce un non-const std::string,
quindi si puo' chiamare resize() senza problemi.
	Mauro

 Mauro
ciao Franz

dello stesso tipo.
No, se c'e` un cast (anche implicito)...
Es.
class A {};
class B : public A {};
int main() {
	A& a = *(new B);
	return 0;
}
Questo codice mi pare perfettamente legale...
Paolo

 quanti ne abbia già...:)
Il gcc 2.95.2 (
http://gcc.gnu.org/
) e' abbastnza vicino allo
standard; bisogna pero' fare attenzione che
- le versioni precedenti sono molto meno vicine alo standard,
  in particolare egcs 1.0, gcc 2.8 e precedenti sono praticamente
  inutilizzabili
- assieme al compilatore _non_ viene fornita di serie anche
  la libreria standard; la libreria fornita con il compilatore
  e' vecchia e molto lontana dallo standard.
Per avere un sistema completo (compilatore + libreria) e' 
necessario procurarsi la libreria da qualche altra parte,
per esempio:
- STLport (
http://www.stlport.org/
)
- cxxrt (
http://www.claas-solutions.de/cxxrt/
)
- Dinkum (
http://www.dinkumware.com/libraries.html
  ) - commerciale
Il KAI C++ (
http://www.kai.com/C_plus_plus/
) e' uno dei migliori 
compilatori C++ in commercio, ma e' abbastanza costoso.
Il Comeau C++ (
http://www.comeaucomputing.com/
), sempre commerciale,
dovrebbe essere un altro buon compilatore, anche se non l'ho mai usato.
E' possibile provarlo online per piccoli frammenti di codice 
all'indirizzo 
http://www.comeaucomputing.com/tryitout/
.
	Mauro

 Es.
[cut - esempio con classi derivate]
Correzione: un (non-const) T& deve essere inizializzato con 
un lvalue dello stesso tipo T oppure di un tipo T1 derivato
publicamente da T.
Non basta che esista una conversione implicita;  anche fra 
int e double c'e' la conversione, ma non si possono inizializzare
int& con double (o double& con int).
	Mauro

 ha scritto nel messaggio
news:8rthvt$9m7$1...@pegasus.tiscalinet.it...

KAI C++ (disponibile per Linux e win NT).
Manlio Perillo

Non basta che esista una conversione implicita; 
Mi riferivo a conversioni sui puntatori, non i tipi puntati...
Ma mi pare che a questo punto non ci siano disaccordi
(in virtu` del significato di una cast (esplicito)).
Paolo