在没有强制转换的情况下,为什么不能在某些情况下引用公共静态const变量?

时间:2013-04-28 01:24:24

标签: c++

以下代码说明了我遇到的一个问题,它无法使用对Def :: DEFAULT的未定义引用进行编译;

但是如果我在main中注释掉第二行它将编译并运行正常,我能够“看到”分配给DEFAULT的值,通过强制转换为int或直接分配给Val类int数据成员。 / p>

template <typename T, T def>
class Def {
 public:
    static const T DEFAULT = def;
    enum {DEFAULT_ENUM = DEFAULT};
};


class Val {
 public:
    Val& operator=(const int &val_in) {
        val = val_in;
        return *this;
    }

    int val;
};


typedef Def<int, 10> Def_t;

Val test_val;

int main()
{
    test_val     =       Def_t::DEFAULT_ENUM;  // works
    test_val     =       Def_t::DEFAULT;       // fails to compile
    test_val     = (int) Def_t::DEFAULT;       // works
    test_val.val =       Def_t::DEFAULT;       // works
}

1 个答案:

答案 0 :(得分:2)

您的代码具有未定义的行为,因为您使用Def_t::DEFAULT而未定义[basic.def.odr]/3

  

每个程序应该只包含该程序中使用的每个非内联函数或变量的一个定义;无需诊断。

类定义中的声明不是定义[class.static.data]/2

  

在类定义中声明静态数据成员不是定义....静态数据成员的定义应出现在包含成员类定义的命名空间范围内。 ...

如果在为Def_t::DEFAULT添加声明时代码仍然无法编译,那么这是编译器中的错误。可以通过在命名空间范围中放置以下内容来添加定义:

template<typename T, T def>
T const Def<T, def>::DEFAULT;

如果您希望在T不是整数类型或枚举类型时使用它,请将DEFAULT的初始化器放在此命名空间范围定义中,而不是放在类定义中。