2011-07-01 14 views
18

Actualmente estoy intentando comprender la nueva inicialización uniforme de C++ 0x. Desafortunadamente, abandoné el uso de la inicialización uniforme de referencias. Ejemplo:Inicialización uniforme de referencias

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

Este ejemplo funciona 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] 

(actualización Comeau lanza un error de ese ejemplo, así que tal vez no debería gcc compila también)

Ahora, si utilizo un tipo de datos personalizado en lugar de un entero, ya no funciona:

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] 

Desafortunadamente, no encontré la sección relevante en el borrador estándar. Mi conjetura es que estoy mal entendido el uso de inicialización uniforme, como Comeau se queja con este mensaje:

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

Por lo tanto, puede que alguien de ustedes me punto en la dirección correcta?


En caso de que usted quiere saber por qué esta pregunta es relevante y por qué no sólo tiene que utilizar Y &ref(y): Me gustaría ser capaz de utilizar la inicialización uniforme en la lista de inicialización de un constructor:

class X { }; 

class Y { 
    const X& x; 

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

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

Esto falla con el mismo mensaje de error que el anterior.

Nota:

  • estoy usando LANG=C para permitir mensajes de error en inglés.
  • gcc versión: 4.6.1
+0

gcc 4.4.1 no se compila el primer ejemplo ya sea: 'uniform_init_of_ref.cpp: 3: error: ISO C++ prohíbe el uso de lista de inicialización para inicializar referen ce 'ref'' – rmflow

+2

@rmflow: GCC4.4 no lo hace completamente implementar una inicialización uniforme. –

+0

Puedes usar el ordinario 'x (xx)' en tu lista de inicializadores de constructores, por lo que no veo la necesidad de usar uniformes novedosos :-) –

Respuesta

6

De acuerdo con el párrafo 8.5.4.4 del N2672 debería decir:

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. ]

cual (si he entendido bien) significa inicialización uniforme de referencias ellas se une a la nueva instancias anónimas, por lo que me parece que es bastante inútil. Eso todavía no explica por qué uno funciona y el otro no; deberían comportarse igual (a menos que Y tenga algunos constructores explícitos).

+0

Por lo tanto, en el primer ejemplo, hacer 'ref = 42' ** no ** modificará' a'. –

+0

@ alexandre-c asignar a 'ref' en el primer ejemplo cambia el valor de' a' aquí. – evnu

+0

@evnu: este comportamiento no se ajusta a lo que dice @Jan. ¿Lo revisaste con Comeau? –

Cuestiones relacionadas