2011-07-01 5 views
18

J'essaie actuellement de comprendre la nouvelle initialisation uniforme de C++ 0x. Malheureusement, j'ai trébuché sur l'utilisation de l'initialisation uniforme des références. Exemple:Initialisation uniforme des références

int main() { 
    int a; 
    int &ref{a}; 
} 

Cet exemple fonctionne très bien:

% LANG=C g++ uniform_init_of_ref.cpp -std=c++0x -o uni -Wall -Wextra 
uniform_init_of_ref.cpp: In function `int main()': 
uniform_init_of_ref.cpp:3:10: warning: unused variable `ref' [-Wunused-variable] 

(Update Comeau lance une erreur pour cet exemple, alors peut-être gcc ne devrait pas le compiler ainsi)

Maintenant, Si j'utilise un type de données personnalisé au lieu d'un entier, cela ne fonctionne plus:

class Y 
{}; 

int main() 
{ 
    Y y; 
    Y &ref{y}; 
} 

% LANG=C g++ initialization.cpp -std=c++0x -o initialization -Wall -Wextra 
initialization.cpp: In function `int main()': 
initialization.cpp:9:13: error: invalid initialization of non-const reference of type `Y&' from an rvalue of type `<brace-enclosed initializer list>' 
initialization.cpp:9:8: warning: unused variable `ref' [-Wunused-variable] 

Malheureusement, je n'ai pas trouvé la section pertinente dans le brouillon standard. Je pense que je comprends mal l'utilisation d'initialisation uniforme, comme Comeau se plaint avec ce message:

ComeauTest.c(9): error: reference variable "ref" requires an initializer 
     Y &ref{y}; 

Ainsi, quelqu'un peut vous me diriger dans la bonne direction?


Dans le cas où vous voulez savoir pourquoi cette question est pertinente et pourquoi je ne pas simplement utiliser Y &ref(y): Je voudrais pouvoir utiliser l'initialisation uniforme dans la liste d'initialisation d'un constructeur:

class X { }; 

class Y { 
    const X& x; 

    public: 
     Y (const X& xx): 
      x{xx} 
     {} 
}; 

int main() { 
    X x; 
    Y y{x}; 
} 

Échec avec le même message d'erreur que ci-dessus.

Note:

  • J'utilise LANG=C pour activer les messages d'erreur en anglais.
  • gcc version: 4.6.1
+0

gcc 4.4.1 ne compile pas le premier exemple, soit: 'uniform_init_of_ref.cpp: 3: Erreur: ISO C++ interdit l'utilisation de la liste d'initialisation pour initialiser référen CE « ref'' – rmflow

+2

@rmflow: gcc4.4 ne pas pleinement implémenter une initialisation uniforme. –

+0

Vous pouvez utiliser l'ordinaire 'x (xx)' dans votre liste d'initialisation de constructeur, autant que je peux voir pas besoin de ce truc uniformément nouveau :-) –

Répondre

6

Selon N2672 le paragraphe 8.5.4.4 devrait dire:

Otherwise, if T is a reference type, an rvalue temporary of the type referenced by T is list-initialized, and the reference is bound to that temporary. [ Note: As usual, the binding will fail and the program is ill-formed if the reference type is an lvalue reference to a non-const type. ]

qui (si je comprends bien) signifie l'initialisation uniforme des références les lie à nouveau instances anonymes, donc il me semble que c'est assez inutile. Cela n'explique toujours pas pourquoi on travaille et pas l'autre; ils devraient se comporter de la même manière (sauf si Y a des constructeurs explicites).

+0

Ainsi, dans le premier exemple, faire 'ref = 42' ** ne modifiera pas ** a'. –

+0

@ alexandre-c assignant 'ref' dans le premier exemple change ici la valeur de' a'. – evnu

+0

@evnu: ce comportement n'est pas conforme à ce que @Jan cite. Avez-vous vérifié auprès de Comeau? –