模板化类的静态常量
Static constants of templated class
我一直在使用gcc 4.8.2中的模板类和常量,并遇到了一个有趣的链接器错误:
#include <iostream>
using namespace std;
template <class T, int m>
class A {
public:
static const T param = m;
T value;
A(const T &value, const T &dummy = T()) : value(value) {}
};
// Works with this
// template <class T, int m>
// const T A<T, m>::param = m;
template <class T, int m>
A<T, m> operator +(const A<T, m> &a, const A<T, m> &b) {
if (a.param != b.param) exit(1);
// Works if I replace a.param with 0
return A<T, m>(a.value + b.value, a.param);
}
int main() {
A<int, 2> v = A<int, 2>(1) + A<int, 2>(2);
cout << v.value << endl;
return 0;
}
在当前状态下编译代码会给出一个链接器错误,告诉我A::param
没有定义。
在Visual Studio 2008中尝试这段代码,它编译和链接没有任何问题。在gcc上,当我使用param
常数的外部声明,或者如果我将a.param
替换为0或指示行上的任何内容时,它都会编译。
我不明白的是为什么包含if
语句的行可以使用a.param
而没有编译错误,而我不能将a.param
传递给构造函数而不对外声明。
所以我的问题是:我什么时候需要在外部声明param
, if
语句和构造函数调用中的访问有什么区别?我测试的两个编译器中,哪一个在这里做了"正确"的事情,哪一个扩展了标准?
再玩一会儿,我意识到当我为g++指定-O2标志时,它也可以工作。
template <class T, int m>
class A {
public:
static const T param = m;
T value;
A(const T &value, const T &dummy = T()) : value(value) {}
};
// Works with this
// template <class T, int m>
// const T A<T, m>::param = m;
//gotta define it here!
template <class T, int m>
const T A<T, m>::param;
template <class T, int m>
A<T, m> operator +(const A<T, m> &a, const A<T, m> &b) {
if (a.param != b.param) exit(1);
// Works if I replace a.param with 0
return A<T, m>(a.value + b.value, a.param);
}
int main() {
A<int, 2> v = A<int, 2>(1) + A<int, 2>(2);
std::cout << v.value << std::endl;
return 0;
}
从这里如果静态数据成员是const整型或const枚举类型,可以在静态数据成员声明中指定常量初始化式。这个常量初始化式必须是一个整型常量表达式。注意,常量初始化式不是定义。您仍然需要在封闭命名空间中定义静态成员。
在正常工作的情况下,编译器是不兼容的。微软是不兼容的,因为微软几乎从不兼容,g++和-O2有点有趣,但无论哪种情况,你都没有定义!
编辑:根据经验,我总是在类之外定义静态常量成员变量,因为这样我就不必记住它了。在这种情况下,如果T不是整数类型,例如浮点数,那么类A将无效。因此,与其围绕异常做任何模式,我更倾向于坚持使用规则周围的模式。
相关文章:
- 私有类型的静态常量成员
- 分离一个静态常量 std::thread?
- 从另一个静态常量数组初始化静态常量数组(只需少量计算)
- 我可以在运行时重新定义在 OpenCascade/OCCT 标头中定义的 c++ 静态常量吗?
- 如何为静态常量模板化专用整数值分配存储
- 使用什么代替"静态常量 TCHAR *"
- C++ 模板中的静态常量初始化顺序
- 如何在编译时解析静态常量 std::string?
- 关于静态常量数据模因的声明和定义的混淆
- 将 static_cast<int>(-15) 分配给静态常量字符类型变量
- 为什么在第二类中使用静态常量会在第一类中给出编译器错误?
- 静态常量与常量局部变量,哪一个性能更好
- 如何在模板类中设置静态常量变量
- public:静态常量字符串声明/初始化问题
- 有没有办法声明一个公共静态常量,该常量将使用 constexpr 在源文件中定义(有什么区别)?
- 对静态常量积分类型的未定义引用
- 全局变量中的静态常量与常量
- c++ 类中的静态常量变量和常量变量在存储方面是否有区别
- 避免在静态常量类上定义但不使用
- 指向静态常量对象的共享指针?