如何编写适用于 32 位和 64 位的 std::bitset 模板 [英] How to write a std::bitset template that works on 32 and 64-bit

查看:32
本文介绍了如何编写适用于 32 位和 64 位的 std::bitset 模板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑下面的代码

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 位编译会报错.

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.

显然,解决此问题的一种方法是将 bitset<8> 更改为 bitset<8ul>,但是有什么方法可以重新编写 template 部分,以便它可以使用任何默认值数字文字的解释是?

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?

推荐答案

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

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:
        ...

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

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]);

但在其他情况下,类型必须匹配.请注意,这仅适用于自动推导的模板参数,但不适用于显式给定的模板参数.原因是对于推导的参数,编译器会尝试找出实际模板参数与其从调用中推导出的参数之间的最佳匹配.许多其他隐式转换是不允许的.如果您将参数显式化(忽略现在使用 size_t 的解决方案来说明我的观点),则您可以使用完整的转换范围

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
}

这篇关于如何编写适用于 32 位和 64 位的 std::bitset 模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆