c++ c++11 g++ reference uniform-initialization

c++ - Inicialización uniforme de referencias.



c++11 g++ (1)

Actualmente estoy tratando de entender la nueva inicialización uniforme de C ++ 0x. Desafortunadamente, me tropecé con el uso de la inicialización uniforme de las referencias. Ejemplo:

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]

(La actualización de Comeau arroja un error para ese ejemplo, así que tal vez gcc no debería compilarlo también)

Ahora, si uso 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. Supongo que no entiendo el uso de la inicialización uniforme, ya que Comeau se queja con este mensaje:

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

Entonces, ¿alguien de ustedes puede señalarme en la dirección correcta?

En caso de que desee saber por qué esta pregunta es relevante y por qué no solo uso Y &ref(y) : me gustaría poder usar una 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 anterior.

Nota:

  • Estoy usando LANG=C para habilitar los mensajes de error en inglés.
  • versión gcc: 4.6.1

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

De lo contrario, si T es un tipo de referencia, un rvalue temporal del tipo referenciado por T se inicializa en la lista, y la referencia está vinculada a ese temporal. [Nota: Como es habitual, la vinculación fallará y el programa no se formará correctamente si el tipo de referencia es una referencia de valor a un tipo no constante. ]

lo que (si lo comprendo correctamente) significa que la inicialización uniforme de las referencias las une a nuevas 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).