C++通过模板限制 unsigned int

发布于 2024-12-29 00:34:10 字数 559 浏览 3 评论 0原文

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

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

I'm using a template to convert integral types into a string representation of their binary values. I used the following:

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;
}

It works for int but doesn't compile with 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

Could you explain why?

EDIT:

Yes, I'm using VS2010

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

痕至 2025-01-05 00:34:10

不是您的 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();
}

Not your ToBinary call is ambiguous, its the constructor call of bitset with an unsigned value. Unfortunately this is a VC++ Bug: http://connect.microsoft.com/VisualStudio/feedback/details/532897/problems-constructing-a-bitset-from-an-unsigned-long-in-the-vc-rc

Edit - Workaround:

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();
}
温柔少女心 2025-01-05 00:34:10

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

第一个是:

20.5.1 bitset 构造函数 [bitset.cons]< /强>

constexpr bitset(unsigned long long val) noexcept;

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

然后还有这个,我怀疑当您使用 unsigned int 调用它时,这可能会导致事情变得不明确

模板 
显式位集(
常量 charT* 字符串,
类型名 basic_string::size_type n = basic_string::npos,
charT 零 = charT('0'), charT 一 = charT('1'));

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

bitset( n == basic_string::npos ? basic_string(str) :
basic_string(str, n), 0, n, 0, 1)

If you look at the standard (FDIS n3290), then you see that std::bitset has multiple constructors:

First there is this one:

20.5.1 bitset constructors [bitset.cons]

constexpr bitset(unsigned long long val) noexcept;

Effects: Constructs an object of class bitset, initializing the
first M bit positions to the corresponding bit values in val. M is the
smaller of N and the number of bits in the value representation (3.9)
of unsigned long long. If M < N, the remaining bit positions are
initialized to zero.

Then there is also this one, which I suspect might be might cause things to become ambigious, when you call it with 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’));

Effects: Constructs an object of class bitset as if by

bitset( n == basic_string<charT>::npos ? basic_string<charT>(str) :
basic_string<charT>(str, n), 0, n, zero, one)
紅太極 2025-01-05 00:34:10

你用的是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";
}

Are you using VC10? There is already an issue reported: Microsoft connect. Also I'd guess that you might be able to fix it by casting the type to int if it is 32 bit, like this:

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

This can be done inside of the method as well if needed. The result of the reinterpret should not be used for arithmetics anymore, though. ;)

Works fine as workaround for me (but looks quite ugly)

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";
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文