テンプレートのメタプログラミングを掘り起こすと、C++の列挙型の範囲で奇妙な動作が検出されました。 警告:式で整数オーバーフローが発生する。実際にはenumの範囲外の値は望ましくないようだ。テンプレートクラスのときにenumで整数オーバーフローが発生する
#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;
}
コンパイル出力:ここでは、コードです
test.cpp:7:19: warning: integer overflow in expression [-Woverflow]
enum { result = 2*pow<i-1>::result};
^
test.cpp:7:7: warning: overflow in constant expression [-fpermissive]
enum { result = 2*pow<i-1>::result};
プログラムの出力:
pow<2>: 4
pow<4>: 16
pow<30>: 1073741824
pow<31>: -2147483648
max test: 4294967295
max test_2: 18446744073709551615
がクラスPOWで列挙型が小さい範囲を持っているのはなぜ?限り、私が理解する限り、私は別のクラスがインスタンス化されているので、それは別の列挙型を持っています。結果として、 'i'> 31の場合、enumはtest_2のように64ビットでなければなりません。どこが間違っていますか?
私はgcc 4.8とgcc 5.4を試しましたが、結果は同じです。
C++ 11を使用している場合は、 'enum'の代わりに' static constexpr'変数を使用するか、 'enum:long int {...};' – Nelfeal