2013-10-12 20 views
6

Alcuni esempi di codice della "quarta edizione del linguaggio di programmazione C++" mi confondono. Ecco i miei casi di test.l'inizializzazione del lvalue non riesce

Env versione di gcc 4.6.3 (Debian 4.6.3-14 + rpi1) con -std = C++ 0x

  • Code1string var {"Cambridge"}; string& r1 {var};compilazione fallisce
  • Code2string var {"Cambridge"}; string& r1 = var;Compilazione riuscire
  • Code3string var {"Cambridge"}; string&& r1 {var};Compilazione riuscire
  • Code1 Compilazione Fails cong++ -g -DLINUX -std=c++0x -c src/dummy.cpp -o src/dummy.o src/dummy.cpp: In function ‘int main(int, char**)’: src/dummy.cpp:26:17: error: invalid initialization of non-const reference of type ‘std::string& {aka std::basic_string<char>&}’ from an rvalue of type ‘<brace-enclosed initializer list>’ make: *** [src/dummy.o] Error 1
  • Code1 dovrebbe essere ok, secondo i libri. Sezione 7.7.2 dal momento che var è un lvalue, ma perché il codice 1 non funziona ma codice3 funziona nella mia situazione?
+1

Sembra un bug in GCC (incluso 4.8), Clang accetta la versione 1 bene. –

+3

Si è imbattuto in [DR1288] (http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#1288). Si spera che i compilatori più recenti implementeranno la risoluzione proposta anziché il difetto standardizzato. – dyp

risposta

3

Non riesce perché tenta di associare un valore di rvalue a un riferimento di lvalue non conforme.

8.5.4 Elenco inizializzazione

[# 3]

- Altrimenti, se T è un tipo di riferimento, un prvalue temporanea del tipo fa riferimento T è lista- inizializzato e il riferimento è associato a quello temporaneo. [Nota: come al solito, il binding fallirà e il programma è mal formato se il tipo di riferimento è un riferimento di lvalue a un tipo non const. - nota end]

Verifica questo esempio per verificare che r1 è destinata a un oggetto distinto

#include <string> 
#include <iostream> 

int 
main() { 
    std::string var {"Cambridge"}; 
    const std::string& r1 {var}; 
    const std::string& r2 (var); 

    var.clear(); 

    std::cout << "var = " << var << std::endl; 
    std::cout << "r1 = " << r1 << std::endl; 
    std::cout << "r2 = " << r2 << std::endl; 
} 

e contrasto che a r2.

PS. Ora si pone la questione, perché il seguente non manca in base alle considerazioni di cui sopra:

int x; 
int &y { x }; 

lo standard dice (nello stesso luogo come sopra, ma la prossima clausola):

- In caso contrario, , se l'elenco di inizializzazione ha un singolo elemento, l'oggetto o il riferimento viene inizializzato da quell'elemento;

Questa clausola menzioni esplicitamente riferimento, in altre parole, l'inizializzazione di un punto di riferimento non è descritto in una singola clausola, ma ci sono un paio di possibilità (forse provato in ordine di clausole?), Il che spiega il motivo per cui int & si comporta in questo modo.

+0

Grazie per la risposta. Quindi significa che il codice del libro è sbagliato? Stava cercando di dire che questo è un codice demo corretto 'string & r1 {var}; // riferimento di lvalue, bind da r1 a var (un lvalue) 'Sezione 7.7.2 del libro –

+0

Potresti darmi qualche informazione sul tuo compilatore? Hai ottenuto lo stesso "errore di compilazione" con la compilazione del codice di esempio? –

+0

GCC 4.8.1 utilizzato qui. Sì, penso che il libro sia in errore e ce ne sia un altro là 'stringa && rr2 {var};' dovrebbe funzionare. – chill

Problemi correlati