Referencia colapsando?

Al tratar de resolver este problema , algo me hizo preguntarme. Considera el siguiente código:

template  struct foo { foo(T const& x) : data(x) {} T data; }; 

Parece que puedo construir un objeto de tipo foo sin error, el hipotético T const& const& entendido como T const& .

También parece que esto se llama colapso de referencia , pero nunca escuché este término antes (ver comentarios en la pregunta vinculada).

¿Esto está generalizado? ¿Es este estándar?

En C ++ 03, no era legal hacer lo siguiente

 typedef int &ref; ref &r = ...; // reference to reference! 

Esto con frecuencia causa problemas para las personas que comstackn con comstackdores C ++ 03 realmente estrictos o antiguos (GCC4.1 y Comeau 8/4/03 no les gusta lo anterior) porque los enlazadores de objetos de función estándar no se ocupan de la “referencia” para hacer referencia a “situación, y ocasionalmente crear tales tipos ilegales”.

En C ++ 0x esto se llama “colapso de referencia”, sí. La mayoría de los comstackdores actuales de C ++ 03 hacen eso (es decir, un T& donde T denota que un tipo de referencia es T otra vez), aplicando retroactivamente la regla. La biblioteca boost.call_traits hace que sea fácil declarar dichos parámetros de función, de modo que no se produzca la situación de “referencia a referencia”.

Tenga en cuenta que la const allí no tiene ningún efecto. Un const aplicado sobre un tipo de referencia se ignora silenciosamente. Entonces, incluso si el comstackdor admite colapso de referencia, lo siguiente no es legal

 int const x = 0; // illegal: trying to bind "int&" to "int const"! ref const& r = x; 

De acuerdo con esto , en C ++ 98 solo hubo soporte limitado para el colapso de referencia:

En C ++ 98, solo hay una regla de colapso de referencia: T & y una referencia a una referencia, colapsa a T &:

 void g(int & ri) {++ri;} // int& & -> int& void f(int & ri) {g(ri);} 

Incluso allí, es ilegal intentar declarar una variable que es una referencia a una referencia:

 int ben; int& bill(ben); // OK int & & bob(bill); // error C2529: 'bob' : reference to reference is illegal