静态常量字段初始化顺序中是否有陷阱?
template <typename T>
struct constant_test {
static const T PI;
static const T FULL_CIRCLE;
static const T HALF_CIRCLE;
static const T DEG_TO_RAD;
};
template <typename T> const T constant_test<T>::PI = 3.141592653589f;
template <typename T> const T constant_test<T>::FULL_CIRCLE = 360.0f;
template <typename T> const T constant_test<T>::HALF_CIRCLE = constant_test<T>::FULL_CIRCLE / 2;
template <typename T> const T constant_test<T>::DEG_TO_RAD = constant_test<T>::PI / constant_test<T>::HALF_CIRCLE;
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) {
// uncomment to make it work
// float test_ref = constant_test<float>::HALF_CIRCLE;
char buf[128];
sprintf_s(buf, 128, "Value: %f", constant_test<float>::DEG_TO_RAD);
OutputDebugStringA(buf); // prints "Value: 1.#INF00"
return 0;
}
表达式constant_test<float>::DEG_TO_RAD
神奇地返回-Infinity
如果我删除模板参数并使它们只浮动,则正确评估常量(0.017453)
如果我添加对HALF_CIRCLE常量的引用,那么它也会被正确评估
我正在使用MSVC 2013 SP 1。
为什么呢? 我错过了什么?
答案 0 :(得分:1)
此代码打印出正确的值(g ++ 4.8.2,OS X):
#include <iostream>
using namespace std;
template <typename T>
struct constant_test {
static const T PI;
static const T FULL_CIRCLE;
static const T HALF_CIRCLE;
static const T DEG_TO_RAD;
};
template <typename T> const T constant_test<T>::PI = 3.141592653589f;
template <typename T> const T constant_test<T>::FULL_CIRCLE = 360.0f;
template <typename T> const T constant_test<T>::HALF_CIRCLE = constant_test<T>::FULL_CIRCLE / 2;
template <typename T> const T constant_test<T>::DEG_TO_RAD = constant_test<T>::PI / constant_test<T>::HALF_CIRCLE;
int main()
{
// uncomment to make it work
//float test_ref = constant_test<float>::HALF_CIRCLE;
cout << "Value: " << constant_test<float>::DEG_TO_RAD << endl; // correct result
char buf[128];
sprintf(buf, "Value: %f", constant_test<float>::DEG_TO_RAD );
cout << buf << endl; // again correct
return 0;
}
输出:
Value: 0.0174533
Value: 0.017453
静态常量按顺序初始化,请参阅https://stackoverflow.com/a/10011133/3093378,因此在显示时应该初始化constant_test<T>::DEG_TO_RAD
(从上面的代码看起来是这样)。