【问题标题】:Extract signed-ness of template type?提取模板类型的签名?
【发布时间】:2015-07-06 08:29:43
【问题描述】:

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

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

我试图避免专业化,因为这只会重复代码(唯一要改变的是base 的签名)。我还试图避免将base 转换为T,以防它是像Integer 这样的非POD 类型(针对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;
}

【问题讨论】:

  • 在您的情况下,应将a 转换为unsigned。 (它会修复边缘情况(IntToString&lt;signed char&gt;(-128))。
  • C++11 类型特征库来自 boost。我强烈建议使用 C++98/03 中的 Boost.TypeTraits 库,而不是推出自己的元函数。
  • @sbabbi - 该库使用 C++03,并且没有外部依赖项。此外,Boost 无法通过验收测试。最后,Boost 不适用于某些基于 Windows 的配置。

标签: c++ templates unsigned signed


【解决方案1】:

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){

【讨论】:

  • 非常感谢。它在现代 GCC 和 Clang 上就像一个魅力。接下来是使用 OpenBSD 和 Visual Studio 进行的一轮测试(跨平台库有时会很痛苦)。
【解决方案2】:

您可以使用is_signed 函数检查一个类型是否已签名,以及使用is_unsigned 函数是否未签名。

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

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

【讨论】:

  • 谢谢,但我说的是 C++98 和 C++03。
【解决方案3】:

T 的符号可以推导出为std::is_signed&lt;T&gt;::valuehttp://en.cppreference.com/w/cpp/types/is_signed

还可以查看整个 type support 库,了解有关类型静态属性的最终其他类似功能。

base 的类型应该是

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

【讨论】:

  • 谢谢,但我说的是 C++98 和 C++03。
  • @jww 你可以自己实现这些元功能。网上有一堆实现。
  • @TartanLlama 哎呀,我把你和写答案的人搞混了。对不起。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-06
  • 2016-07-20
  • 2011-07-05
  • 1970-01-01
  • 2023-02-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多