提取模板类型的签名?

时间:2015-07-06 08:29:44

标签: c++ templates unsigned signed

以下代码会生成-Wsign-conversion的警告。它会在第T digit = a % base行生成警告。

我想提取T的签名,然后将base转换为该签名,以压制警告。

我试图避免专业化,因为这只是重复代码(唯一会改变的是base的签名)。我还试图避免将base投射到T,以防它的非POD类型如Integer(使用longs进行优化以进行缩减)。

如何提取T的签名?

相关的,代码库实际上是C ++ 98和C ++ 03,所以它没有一些功能(如Partial template specialization based on “signed-ness” of integer type?中讨论的那样)。

template <class T>
std::string IntToString(T a, unsigned int base = 10)
{
    if (a == 0)
        return "0";
    bool negate = false;
    if (a < 0)
    {
        negate = true;
        a = 0-a;    // VC .NET does not like -a
    }
    std::string result;
    while (a > 0)
    {
        T digit = a % base;
        result = char((digit < 10 ? '0' : ('a' - 10)) + digit) + result;
        a /= base;
    }
    if (negate)
        result = "-" + result;
    return result;
}

3 个答案:

答案 0 :(得分:2)

Pre-C ++ 11您可以使用std::conditional的实现:

template<bool B, class T, class F>
struct conditional { typedef T type; };
template<class T, class F>
struct conditional<false, T, F> { typedef F type; };

然后我们可以编写一个结构来提取类型的签名:

template <typename T>
struct signedness {
    typedef typename conditional<T(-1)<T(0),int,unsigned>::type type;   
};

然后将base声明为该类型:

std::string IntToString(T a, 
    typename signedness<T>::type base = 10){

答案 1 :(得分:0)

您可以使用is_signed funtcion检查某个类型是否已签名,以及是否使用is_unsigned函数进行了无符号签名。

要将类型转换为相应的签名版本,请使用make_signed和相应的未签名版本使用make_unsigned

抱歉,直到现在才读到C ++ 98部分。

答案 2 :(得分:0)

T的签名可以推导为std::is_signed<T>::value http://en.cppreference.com/w/cpp/types/is_signed

还要查看整个type support库,了解关于类型的静态属性的最终其他类似函数。

base的类型为

std::conditional<std::is_signed<T>::value, int, unsigned>::type