在模板类中时枚举中存在整数溢出 挖掘模板元编程,发现了C++中枚举范围的奇怪行为。我得到一个警告:表达式中存在整数溢出,但看起来我实际上不想要超出枚举范围的值。代码如下: #include <iostream> #include <limits> template <int i> class pow { public: enum { result = 2*pow<i-1>::result}; }; template<> class pow<0> { public: enum { result = 1}; }; enum test { one, max = 4294967295 }; enum test_2 { last = 4294967295*2 }; int main() { std::cout << "pow<2>: \t" << pow<2>::result << std::endl; std::cout << "pow<4>: \t" << pow<4>::result << std::endl; std::cout << "pow<30>: \t" << pow<30>::result << std::endl; std::cout << "pow<31>: \t" << pow<31>::result << std::endl; std::cout << "max test: \t" << std::numeric_limits<std::underlying_type<test>::type>::max() << std::endl; std::cout << "max test_2: \t" << std::numeric_limits<std::underlying_type<test_2>::type>::max() << std::endl; return 0; } #包括 #包括 模板 级战俘{ 公众: 枚举{result=2*pow::result}; }; 模板 级战俘{ 公众: 枚举{result=1}; }; 枚举测试{1,max=4294967295}; 枚举测试_2{last=4294967295*2}; int main(){ std::cout

在模板类中时枚举中存在整数溢出 挖掘模板元编程,发现了C++中枚举范围的奇怪行为。我得到一个警告:表达式中存在整数溢出,但看起来我实际上不想要超出枚举范围的值。代码如下: #include <iostream> #include <limits> template <int i> class pow { public: enum { result = 2*pow<i-1>::result}; }; template<> class pow<0> { public: enum { result = 1}; }; enum test { one, max = 4294967295 }; enum test_2 { last = 4294967295*2 }; int main() { std::cout << "pow<2>: \t" << pow<2>::result << std::endl; std::cout << "pow<4>: \t" << pow<4>::result << std::endl; std::cout << "pow<30>: \t" << pow<30>::result << std::endl; std::cout << "pow<31>: \t" << pow<31>::result << std::endl; std::cout << "max test: \t" << std::numeric_limits<std::underlying_type<test>::type>::max() << std::endl; std::cout << "max test_2: \t" << std::numeric_limits<std::underlying_type<test_2>::type>::max() << std::endl; return 0; } #包括 #包括 模板 级战俘{ 公众: 枚举{result=2*pow::result}; }; 模板 级战俘{ 公众: 枚举{result=1}; }; 枚举测试{1,max=4294967295}; 枚举测试_2{last=4294967295*2}; int main(){ std::cout,c++,templates,enums,metaprogramming,C++,Templates,Enums,Metaprogramming,From 非范围枚举 enum name{enumerator=constexpr,enumerator=constexpr,…}(1) (…) 1) 声明其基础类型不固定的非范围枚举类型(在这种情况下,基础类型是int,或者,如果不是所有枚举数值都可以表示为int,则是一种实现定义的更大整数类型,可以表示所有枚举数值。。如果枚举数列表为空,则基础类型就好像枚举有一个值为0的枚举数一样) 因此,在模板1中,编译器似乎选择int,最大值为+-2147483648(符号为31位+1)。在test中,

From

非范围枚举
enum name{enumerator=constexpr,enumerator=constexpr,…}
(1)
(…)
1) 声明其基础类型不固定的非范围枚举类型(在这种情况下,基础类型是int,或者,如果不是所有枚举数值都可以表示为int,则是一种实现定义的更大整数类型,可以表示所有枚举数值。。如果枚举数列表为空,则基础类型就好像枚举有一个值为0的枚举数一样)

因此,在模板1中,编译器似乎选择int,最大值为+-2147483648(符号为31位+1)。在
test
中,编译器似乎意识到这是不够的,并选择最大值为4294967296(32位)的
unsigned int
。在
test\u 2
中,编译器认识到这也是不够的,并选择64位的无符号类型(最大18446744073709551616)

将枚举声明为

enum { result = 2*pow<i-1>::result, randomMax = \*insert anything large here*\};
enum{result=2*pow::result,randomMax=\*在此处插入任何较大的内容*\};

第二个值只需强制编译器选择一个足够长的类型来保存所有需要的值。

如果使用C++11,可以使用
静态constepr
变量而不是
枚举
,或者像这样指定枚举类型:
枚举:long int{…};
首先:
模板
对于大数来说是一个更好的选择。第二:考虑
result=pow::result*2
中的类型。pow::result是一个int,乘以2得到int,因此pow::result是一个int,并且该模式是重复的。没有办法以这种方式更改递归中的类型(因为enum有一个具体的类型,我不知道)。
enum{result=2l*pow::result}
足以实现这一点,因为乘法给出了长类型,然后编译器决定对结果使用什么类型。
pow<2>:         4
pow<4>:         16
pow<30>:        1073741824
pow<31>:        -2147483648
max test:       4294967295
max test_2:     18446744073709551615
enum { result = 2*pow<i-1>::result, randomMax = \*insert anything large here*\};