如何编写适用于 32 位和 64 位的 std::bitset 模板

发布于 2024-07-14 23:43:09 字数 427 浏览 8 评论 0原文

考虑以下代码,

template<unsigned int N> void foo(std::bitset<N> bs)
{ /* whatever */ }

int main()
{
    bitset<8> bar;
    foo(bar);
    return 0;
}

g++ 在 64 位上抱怨这一点,因为 <8> 被解释为 unsigned long int,与模板不完全匹配。 如果我将模板更改为 unsigned long int,则 32 位编译会出错。

显然,解决此问题的一种方法是将 bitset<8> 更改为 bitset<8ul>,但是有没有办法重写 template 部分,以便它可以与数字文字的默认解释一起工作?

Consider the following code

template<unsigned int N> void foo(std::bitset<N> bs)
{ /* whatever */ }

int main()
{
    bitset<8> bar;
    foo(bar);
    return 0;
}

g++ complains about this on 64 bit because the <8> gets interpreted as an unsigned long int, which doesn't exactly match the template. If I change the template to say unsigned long int, then 32-bit compiles complain.

Obviously one way to fix this is to change bitset<8> to bitset<8ul>, but is there any way to re-write the template part so that it will work with whatever the default interpretation of a numeric literal is?

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

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

发布评论

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

评论(3

ゃ人海孤独症 2024-07-21 23:43:09

问题不在于你写的是 8u 还是 8。 问题与函数模板的模板参数的类型有关。 它的类型必须与 std::bitset 声明中使用的类型匹配。 根据标准(23.3.5 节),这是 size_t

namespace std {
    template<size_t N> class bitset {
    public:
    // bit reference:
        ...

数组维度除外,您可以使用任何整数类型(甚至是 bool) - 那么唯一可以接受的大小当然是1):

// better size_t (non-negative), but other types work too
template<int N> void f(char(&)[N]);

但在其他场合,类型必须匹配。 请注意,这仅适用于自动推导的模板参数,但不适用于显式给定的模板参数。 原因是,对于推导的模板参数,编译器会尝试找出实际模板参数与从调用它推导出来的参数之间的最佳匹配。 那么许多其他隐式转换都是不允许的。 如果您将参数显式显示,您将拥有完整的可用转换范围(忽略现在使用 size_t 来表达我的观点的解决方案)

template<int N> void foo(std::bitset<N> bs)
{ /* whatever */ }

int main() {
    bitset<8> bar;
    foo<8>(bar); // no deduction, but full range of conversions
}

The problem isn't whether or not you write 8u or 8. The problem has to do with the type of the template parameter of your function template. Its type has to match the one used in the declaration of std::bitset. That's size_t according to the Standard (section 23.3.5)

namespace std {
    template<size_t N> class bitset {
    public:
    // bit reference:
        ...

The exception are array dimensions, for which you can use any integer type (even bool - then the only size that can be accepted is 1 of course):

// better size_t (non-negative), but other types work too
template<int N> void f(char(&)[N]);

But in other occasions, types have to match. Note that this is only true for autodeduced template arguments, but not for explicitly given ones. The reason is that for deduced ones, the compiler tries to figure out the best match between actual template arguments and what it deduced from the call to it. Many otherwise implicit conversions are disallowed then. You have the full range of conversions available if you put the argument explicit (ignoring the solution of using size_t now to make my point)

template<int N> void foo(std::bitset<N> bs)
{ /* whatever */ }

int main() {
    bitset<8> bar;
    foo<8>(bar); // no deduction, but full range of conversions
}
故乡的云 2024-07-21 23:43:09

使用size_t。 至少 MSDN 是这么说的。

Use size_t. So sayeth the MSDN at least.

爱她像谁 2024-07-21 23:43:09

无论平台如何,数字文字都应解释为 int

a numeric literal should be interpreted as an int no matter the platform

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