2

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

但是,如果我注释掉 main 中的第二行,它将编译并运行良好,我可以通过强制转换为 int 或直接分配给 Val 类 int 数据成员来“查看”分配给 DEFAULT 的值。

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
}
4

1 回答 1

2

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

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

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

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

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

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

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

于 2013-04-28T02:33:25.150 回答