通过模板的无符号int的C ++限制

时间:2012-01-25 10:47:28

标签: c++ templates stl binary limits

我正在使用模板将整数类型转换为二进制值的字符串表示形式。我使用了以下内容:

template<typename T>
std::string ToBinary(const T& value)
{
    const std::bitset<std::numeric_limits<T>::digits + 1> bs(value);
    const std::string s(bs.to_string());

    return s;
}

它适用于int但不使用unsigned int编译:

unsigned int buffer_u[10];
int buffer_i[10];
...
ToBinary(buffer_i[1]); //compile and works
ToBinary(buffer_u[1]); //doesn't compile -- ambiguous overload

你能解释一下原因吗?

编辑:

是的,我正在使用VS2010

3 个答案:

答案 0 :(得分:4)

不是你的ToBinary调用是不明确的,它是bitset的构造函数调用,带有无符号值。不幸的是,这是一个VC ++ Bug:http://connect.microsoft.com/VisualStudio/feedback/details/532897/problems-constructing-a-bitset-from-an-unsigned-long-in-the-vc-rc

修改 - 解决方法:

template<>
std::string ToBinary<unsigned int>(const unsigned int& value)
{
    const std::bitset<std::numeric_limits<unsigned int>::digits> bs(static_cast<unsigned long long>(value));
    return bs.to_string();
}

答案 1 :(得分:0)

您使用的是VC10吗?已经报告了一个问题:Microsoft connect.此外我猜你可以通过将类型转换为int(如果它是32位)来修复它,如下所示:

string s = ToBinary(*reinterpret_cast<int*>(&buffer_u[1]));

如果需要,这也可以在方法内部完成。不过,重新解释的结果不应再用于算术。 ;)

对我来说工作正常(但看起来很难看)

template<typename T>
std::string ToBinary(const T& value)
{
    switch (sizeof(T))
    {
    case 8:
        return std::bitset<std::numeric_limits<T>::digits + 1>(*reinterpret_cast<const long*>(&value)).to_string();
    case 4:
        return std::bitset<std::numeric_limits<T>::digits + 1>(*reinterpret_cast<const int*>(&value)).to_string();
    case 2:
        return std::bitset<std::numeric_limits<T>::digits + 1>(*reinterpret_cast<const short*>(&value)).to_string();
    case 1:
        return std::bitset<std::numeric_limits<T>::digits + 1>(*reinterpret_cast<const char*>(&value)).to_string();
    }
    return "n/a";
}

答案 2 :(得分:0)

如果您查看标准(FDIS n3290),那么您会看到std::bitset有多个构造函数:

首先是这一个:

20.5.1 bitset constructors [bitset.cons]

  

constexpr bitset(unsigned long long val) noexcept;

     

效果:构造一个类bitset的对象,初始化   第一个M位位置为val中的相应位值。 M是   N中的较小值和值表示中的位数(3.9)   无符号长的。如果M < N,剩余的位位置   初始化为零。

然后还有一个,当你用unsigned int

打电话时,我怀疑它可能会导致事情变得暧昧
template <class charT>
explicit bitset(
const charT* str,
typename basic_string<charT>::size_type n = basic_string<charT>::npos,
charT zero = charT(’0’), charT one = charT(’1’));
     

效果:构造类bitset的对象,就像通过

一样
bitset( n == basic_string<charT>::npos ? basic_string<charT>(str) :
basic_string<charT>(str, n), 0, n, zero, one)