Получить вариант со знаком / без знака целочисленного параметра шаблона без явных черт - PullRequest
19 голосов
/ 13 мая 2010

Я ищу, чтобы определить класс шаблона, чей параметр шаблона всегда будет целочисленным типом. Класс будет содержать два члена, один из которых типа 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 для каждого целочисленного типа. Это небольшая дополнительная работа по копированию и вставке (небрежное использование макросов), но исправная.

Однако мне теперь любопытно - есть ли другой способ определения подписи целочисленного типа и / или использования беззнакового варианта типа без необходимости вручную определять класс Traits для каждого типа? Или это единственный способ сделать это?

Ответы [ 2 ]

22 голосов
/ 13 мая 2010

Ответ в <type_traits>

Для определения подписи типа используйте std::is_signed и std::is_unsigned.

Для добавления / удаления подписи есть std::make_signed и std::make_unsigned.

3 голосов
/ 13 мая 2010

Если вы не можете или не хотите зависеть от функций TR1 / C ++ 0x, Boost.TypeTraits также предлагает вам make_unsigned<> и др.

...