Holen Sie sich die signierte/nicht signierte Variante eines Ganzzahl -Vorlagenparameters ohne explizite Merkmale
-
26-09-2019 - |
Frage
Ich möchte eine Vorlagenklasse definieren, deren Vorlagenparameter immer ein ganzzahliger Typ sein wird. Die Klasse enthält zwei Mitglieder, eine vom Typ T
, und die andere als die nicht signierte Variante des Typs T
- dh wenn T == int
, dann T_Unsigned == unsigned int
. Mein erster Instinkt war, dies zu tun:
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 habe dann darüber nachgedacht, eine partielle Vorlagenspezialisierung zu verwenden, wie 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;
/* ... */
};
Dies funktioniert, solange Sie sich teilweise spezialisiert haben UnsignedType
zum jeder Ganzzahltyp. Es ist ein bisschen zusätzliche Kopie-Paste-Arbeit (salierter Gebrauch von Makros), aber bedürftig.
Ich bin jedoch jetzt neugierig-gibt es eine andere Möglichkeit, die signierte Nahrung eines ganzzahligen Typs zu bestimmen und/oder die nicht signierte Variante eines Typs zu verwenden, ohne manuell eine Merkmalklasse pro Typ zu definieren? Oder ist dies der einzige Weg, dies zu tun?
Lösung
Die Antwort ist in <type_traits>
Zur Bestimmung der signierten Nutzung einer Typ Verwendung std::is_signed
und std::is_unsigned
.
Zum Hinzufügen/Entfernen der Signed-Ness gibt es std::make_signed
und std::make_unsigned
.
Andere Tipps
Wenn Sie nicht von TR1/C ++ 0x -Funktionen abhängen können oder nicht, sind Sie nicht auf TR1/C ++ 0x abhängig. Boost.Typraits bietet Ihnen auch an make_unsigned<>
et al.