2010-05-13 19 views
17

Je cherche à définir une classe modèle dont le paramètre template sera toujours un type entier. La classe contiendra deux membres, l'un de type T, et l'autre comme variante non signée de type T - c'est-à-dire si T == int, puis T_Unsigned == unsigned int. Mon premier réflexe était de faire ceci:Obtenir la variante signée/non signée d'un paramètre de modèle entier sans traits explicites

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; 
}; 

Mais cela ne fonctionne pas. Je me suis alors pensé à utiliser la spécialisation de modèle partiel, comme suit:

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; 
    /* ... */ 
}; 

Cela fonctionne, tant que vous vous spécialisez partiellement UnsignedType pour chaque type entier. C'est un peu plus de travail de copier-coller (slash utilisation judicieuse des macros), mais réparable.

Cependant, je suis curieux: existe-t-il un autre moyen de déterminer la signature d'un type entier et/ou d'utiliser la variante non signée d'un type sans avoir à définir manuellement une classe Traits? Ou est-ce la seule façon de le faire?

Répondre

20

La réponse est dans <type_traits>

Pour la détermination de la signature-ness d'une utilisation de type std :: is_signed et std :: is_unsigned

Pour l'ajout/suppression signé-ness, il est std :: make_signed et std :: make_unsigned

+0

+1 pour "pourquoi n'ai-je pas pensé à cela" réponse. :) –

3

Si vous ne pouvez pas ou ne voulez pas dépendre des fonctionnalités TR1/C++ 0x, Boost.TypeTraits vous offre également make_unsigned<> et al.

+0

+1 - en fait, j'utilise Visual Studio 2005 qui ne supporte pas '' - donc avoir une alternative est pratique. J'ai toujours accepté "" comme réponse car cela fait partie de la bibliothèque standard. –

+0

@Blair: Attention, c'est en fait * "fera partie de" * - sa partie de la prochaine norme qui n'est pas encore sorti. –