静态字段初始化顺序 [英] Static field initialization order

查看:32
本文介绍了静态字段初始化顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

静态常量字段初始化顺序有没有陷阱?

Is there any trap in static constant field initialization order?

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::DEG_TO_RAD 神奇地返回 -Infinity

An expression constant_test<float>::DEG_TO_RAD magically returns -Infinity

如果我删除模板参数并使它们只浮动,那么常量将被正确评估 (0.017453)

If i remove template parameter and make them only float then constant is evaluated correctly (0.017453)

如果我添加对 HALF_CIRCLE 常量的引用,那么它也会被正确评估

If i add reference to HALF_CIRCLE constant then it's also evaluated correctly

我使用的是 MSVC 2013 SP 1.

I'm using MSVC 2013 SP 1.

为什么?我错过了什么?

Why? What i'm missing?

推荐答案

此代码打印出正确的值 (g++4.8.2, OS X):

This code prints out the correct value (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 (从上面的代码看起来是这样).

The static constants are initialized in order, see https://stackoverflow.com/a/10011133/3093378, so you should have constant_test<T>::DEG_TO_RAD initialized when you display it (and it looks it is, from the code above).

这篇关于静态字段初始化顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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