以下代码说明了我遇到的一个问题,它无法使用对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
}
答案 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
的初始化器放在此命名空间范围定义中,而不是放在类定义中。