Я надеюсь определять шаблонный класс, шаблонный параметр которого всегда будет целым типом. Класс будет содержать двух участников, один из типа T
, и другой как неподписанный вариант типа T
- т.е. если T == int
, затем T_Unsigned == unsigned int
. Мой первый инстинкт должен был сделать это:
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;
};
Но это не работает. Я затем думал об использовании частичной шаблонной специализации, как так:
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;
/* ... */
};
Это работает, пока Вы частично специализируетесь UnsignedType
для каждого целого типа. Это - определенная дополнительная работа вставки копии (разрежьте разумное использование макросов), но пригодный к эксплуатации.
Однако мне теперь любопытно - там другой способ определить со знаком из целого типа и/или использовать неподписанный вариант типа, не имея необходимость вручную определять класс Черт на тип? Или действительно ли это - единственный способ сделать это?
Ответ находится в
Для определения подписи типа используйте std :: is_signed
и std :: is_unsigned
.
Для добавления / удаления подписи есть std :: make_signed
и std :: make_unsigned
.
Если вы не можете или не хотите полагаться на функции TR1 / C ++ 0x, Boost.TypeTraits также предлагает вы make_unsigned <>
и др.