2011-01-13 18 views
7

Normalmente, si necesito detectar si un tipo es const solo uso . Sin embargo, tuve problemas al tratar de detectar la constidad de un tipo anidado. Considere la siguiente plantilla rasgos, que está especializada para este tipo const:Detección de const-ness del tipo anidado

template <class T> 
struct traits 
{ 
    typedef T& reference; 
}; 

template <class T> 
struct traits<const T> 
{ 
    typedef T const& reference; 
}; 

El problema es que boost::is_const no parece detectar que traits<const T>::reference es un tipo const.

Por ejemplo:

std::cout << std::boolalpha; 
std::cout << boost::is_const<traits<int>::reference>::value << " "; 
std::cout << boost::is_const<traits<const int>::reference>::value << std::endl; 

Este salidas: false false

¿Por qué no se false true de salida?

Respuesta

13

Como la referencia no es const, es el tipo al que hace referencia que es const. Derecha, no hay referencias const. Así que imagine que la referencia es un puntero, entonces la diferencia es más fácil de entender: int const* no const, int *const es const.

Uso Remove_Reference para obtener el tipo const real:

cout << boost::is_const< 
      boost::remove_reference<int const&>::type>::value << '\n'; 
4

Bueno, ¿ha observado que is_const<int const&>::value es igualmente falsa? Es. Algo así debería estar entre las primeras cosas que intentes para depurar plantillas como esta. Otra cosa que puede hacer uso de una impresora de tipo:

template < typename T > struct print;

Al crear una instancia de que obtendrá lo que T se encuentra en la salida de error, la mayoría de las implementaciones.

Pruebe lo siguiente para resolver su problema actual:

is_const< remove_reference< traits<int const>::reference >::type >::value

+1

s/is_cost/is_const / –

6

Debido a que las referencias no son const. :)

Usted tiene una constante ref-a-(considere un análogo áspera, int const*, donde el pointee int tiene un contexto const, pero el puntero en sí no lo hace). El estándar mezcla la terminología aquí, pero evito el término "const ref" que es altamente engañoso.

Las referencias son intrínsecamente inmutables, ya que solo pueden inicializarse y luego no volverse a enlazar, pero eso no las convierte en const.

Puede eliminar la referencia del tipo con boost::remove_reference (como se indica en otras respuestas).

Cuestiones relacionadas