2010-09-27 20 views
15

Escuché que los objetos temporales solo se pueden asignar a referencias constantes.referencias constantes con typedef y plantillas en C++

Pero este código de error da

#include <iostream.h>  
template<class t> 
t const& check(){ 
    return t(); //return a temporary object 
}  
int main(int argc, char** argv){ 

const int &resCheck = check<int>(); /* fine */ 
typedef int& ref; 
const ref error = check<int>();/*error */ 
return 0; 
} 

el error que se obtiene es invalid initialization of reference of type 'int&' from expression of type 'const int'

Respuesta

21

Este:

typedef int& ref; 
const ref error; 

no hace lo que usted cree. Considere su lugar:

typedef int* pointer; 
typedef const pointer const_pointer; 

El tipo de const_pointer es int* const, noconst int *. Es decir, cuando dices const T estás diciendo "crea un tipo donde T es inmutable"; entonces en el ejemplo anterior, el puntero (no el punto) se hace inmutable.

Las referencias no pueden hacerse const o volatile. Este:

int& const x; 

no tiene sentido, por lo que añadir CV-calificadores a las referencias no tiene ningún efecto.

Por lo tanto, error tiene el tipo int&. No puede asignarle un const int&.


Hay otros problemas en su código. Por ejemplo, esto es ciertamente equivocada:

template<class t> 
t const& check() 
{ 
    return t(); //return a temporary object 
} 

Lo que está haciendo aquí está volviendo una referencia a un objeto temporal que termina su vida útil cuando la función devuelve. Es decir, obtienes un comportamiento indefinido si lo usas porque no hay ningún objeto a la vista. Este no es mejor que:

template<class t> 
t const& check() 
{ 
    T x = T(); 
    return x; // return a local...bang you're dead 
}  

Una prueba mejor sería:

template<class T> 
T check() 
{ 
    return T(); 
} 

El valor de retorno de la función es una temporal, por lo que aún puede probar que pueda temporales de hecho se unen a las referencias constantes .

+0

Buena respuesta. +1 :) –

+0

Gracias. :) – GManNickG

7

El código da error porque el calificador const en const ref error es simplemente ignorado porque 8.3.2/1 dice

Cv-qualified references are ill-formed except when the cv-qualifiers are introduced through the use of a typedef (7.1.3) or of a template type argument(14.3), in which case the cv-qualifiers are ignored.`

Así error tiene tipo int& no const int&.

0

Esto se compila:

 
typedef const int& ref; 
ref error = check<int>(); 

VC++ compilador da una explicación de su error: calificativo aplicado a la referencia de tipo; ignorado El tipo de referencia se debe declarar como constante, const no se puede aplicar más tarde.

8

Es un error muy común para las personas de habla inglesa, debido a la forma en que funciona la gramática inglesa.

Considero que es muy lamentable que la sintaxis de C++ permitiría tanto:

const int // immutable int 
int const // immutable int 

que tienen el mismo significado.

No hace que sea más fácil, de verdad, y no es componibles desde:

const int* // mutable pointer to immutable int 
int* const // immutable pointer to mutable int 

sin duda no tienen el mismo significado.

Y esto, lamentablemente para usted, lo que entra en juego aquí, como explica @GMan.

Si desea evitar este tipo de error en el futuro, tomar el hábito de clasificar sus tipos (const y volatile) en su derecho, entonces usted será capaz de tratar un reemplazo de texto tan simple typedef.

3

Para mantener la coherencia con el Right Left Rule, prefiero usar calificadores 'cv' como ese.

En su ejemplo, me gustaría escribir const ref error = check<int>(); así como

ref const error = check<int>(); // parsed as error is a const reference to an integer 

Como @Prasoon Saurav señalado, calificadores cv se ignoran cuando se introduce a través typedef porque como @GMan también dice que las referencias calificadas cv están mal formados

Por lo tanto, la declaración es efectivamente la siguiente, que por supuesto es un error.

int &error = check<int>(); 

Consulte this para obtener más información.

+1

Esto merece un +1 debido a los enlaces dados en la publicación. –