2010-05-13 31 views
17

Estoy buscando definir una clase de plantilla cuyo parámetro de plantilla siempre será un tipo entero. La clase contendrá dos miembros, uno del tipo T, y el otro como la variante sin firmar del tipo T - es decir, si T == int, luego T_Unsigned == unsigned int. Mi primer instinto fue hacer esto:Obtenga la variante con signo/sin signo de un parámetro de plantilla entera sin rasgos explícitos

template <typename T> class Range { 
    typedef unsigned T T_Unsigned; // does not compile 
public: 
    Range(T min, T_Unsigned range); 
private: 
    T m_min; 
    T_Unsigned m_range; 
}; 

Pero no funciona. luego pensé en el uso de especialización de plantilla parcial, así:

template <typename T> struct UnsignedType {}; // deliberately empty 
template <> struct UnsignedType<int> { 
    typedef unsigned int Type; 
}; 

template <typename T> class Range { 
    typedef UnsignedType<T>::Type T_Unsigned; 
    /* ... */ 
}; 

Esto funciona, siempre y cuando usted se especializa en parte UnsignedType para cada tipo entero. Es un poco de trabajo adicional de copiar y pegar (uso juicioso de macros), pero útil.

Sin embargo, ahora tengo curiosidad: ¿hay alguna otra manera de determinar la firma de un tipo entero y/o usar la variante sin firmar de un tipo, sin tener que definir manualmente una clase de rasgos por tipo? ¿O es esta la única forma de hacerlo?

Respuesta

20

La respuesta está en <type_traits>

Para determinar la-dad firmado de un std tipo de uso :: is_signed y std :: is_unsigned

Para añadir/eliminar-dad firmado, hay std :: make_signed y std :: make_unsigned

+0

+1 para la respuesta "por qué no pensé en eso". :) –

3

Si no puede o no desea depender de las características de TR1/C++ 0x, Boost.TypeTraits también le ofrece make_unsigned<> y otros.

+0

+1 - sucede que estoy usando Visual Studio 2005 que no es compatible con '' - por lo que tener una alternativa es útil. Todavía acepté '' como respuesta, ya que es parte de la Biblioteca estándar. –

+0

@Blair: cuidado, eso en realidad * "será parte de" * - es parte del próximo estándar que aún no ha salido. –

Cuestiones relacionadas