2010-05-13 3 views
17

Ich suche nach einer Template-Klasse, deren Template-Parameter immer ein Integer-Typ ist. Die Klasse enthält zwei Mitglieder, eines vom Typ T, und das andere als die unsignierte Variante vom Typ T - d. H. Wenn T == int, dann T_Unsigned == unsigned int. Mein erster Instinkt war, dies zu tun:Erhalte die signierte/unsignierte Variante eines Integer-Template-Parameters ohne explizite Eigenschaften

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

Aber es funktioniert nicht. Ich dachte dann über partielle Template-Spezialisierung mit, etwa so:

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

Das funktioniert, solange Sie teilweise UnsignedType für jeden Integer-Typen spezialisiert hat. Es ist ein bisschen zusätzliche Copy-Paste-Arbeit (slash vernünftige Verwendung von Makros), aber brauchbar.

Allerdings bin ich jetzt neugierig - gibt es eine andere Möglichkeit, die Signed-Ness eines Integer-Typs zu bestimmen und/oder die unsignierte Variante eines Typs zu verwenden, ohne eine Traits-Klasse pro Typ manuell definieren zu müssen? Oder ist das der einzige Weg, es zu tun?

Antwort

20

Die Antwort ist in <type_traits>

Für die signierte-ness eines Typ Verwendung std :: Bestimmung is_signed und std :: is_unsigned

Zum Hinzufügen/Entfernen von signierten-ness, gibt es std :: make_signed und std :: make_unsigned

+0

+1 für "warum habe ich nicht daran gedacht" Antwort. :) –

3

Wenn Sie nicht auf TR1/C++ 0x Funktionen angewiesen sind oder nicht, Boost.TypeTraits bietet Ihnen auch make_unsigned<> et al.

+0

+1 - wie es passiert, ich benutze Visual Studio 2005, die '' nicht unterstützt - so eine Alternative ist praktisch. Ich akzeptierte immer noch ' 'als Antwort, da es Teil der Standardbibliothek ist. –

+0

@Blair: Vorsicht, das ist eigentlich * "wird Teil von" * - sein Teil des nächsten Standards, der noch nicht out ist. –