6

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

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

4

3 回答 3

4

不是您的 ToBinary 调用是模棱两可的,它是带有无符号值的 bitset 的构造函数调用。不幸的是,这是一个 VC++ 错误: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();
}
于 2012-01-25T11:05:12.200 回答
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";
}
于 2012-01-25T11:08:56.067 回答
0

如果您查看标准(FDIS n3290),您会发现它std::bitset有多个构造函数:

首先是这个:

20.5.1 位集构造函数 [bitset.cons]

constexpr bitset(unsigned long long val) noexcept;

效果:构造一个bitset类的对象,将前M位位置初始化为val中对应的位值。M 是 N 和 unsigned long long 的值表示 (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)
于 2012-01-25T11:09:05.187 回答