可能重复:
C++ - defining static const integer members in class definition
注意:有几个现存的问题是类似的问题,但我已经审查了很多问题,但找不到解释这种行为的答案:
说我有以下代码(在标题文件中)
class Foo {
static const int TEST = 33;
public:
void willItWork(void) {
printf("%d", std::max(TEST, 75)); // embedded platform, no streams
}
};
int main(void) {
Foo tester;
tester.willItWork();
}
这将编译,但不会链接。我收到链接器错误
错误:L6218E:未定义的符号Foo :: TEST(来自foo.o)。
似乎只是将值传递给外部函数会导致问题。在类中的普通表达式或函数中使用TEST
可以正常工作。如果我改为将willItWork()
写为
void willItWork(void) {
int diff = TEST - 23;
printf("%d", diff);
}
没有错误。
我发现另一个引用C ++标准的问题(第9.4.2节):
如果静态数据成员是const integer或const枚举类型,则它在类定义中的声明可以指定一个const-initializer,它应该是一个整数常量表达式。
由于我所做的似乎是“在规则范围内”,任何人都可以想到对这种奇怪行为的任何可能的解释吗?
我在ideone上尝试了类似的代码并且没有问题(但是,我无法模仿确切的结构,即使用头文件)。这是否意味着我使用的链接器不完全符合此处的标准?
非常感谢任何见解。我也可以随时提供更多信息。
答案 0 :(得分:4)
如果编译器认为它需要static
成员变量的地址,例如,在某个时刻将变量绑定到引用时,它将创建相应的未定义符号,并且您必须定义该成员:
int const foo::TEST;
(在一个翻译单元中)。如果编译器只访问该值,则可以在不定义对象的情况下逃脱。除非您需要类型为int
,否则您可以使用enum
代替,并且无需定义成员:
enum { TEST = 33 };
如果我没记错的话,要查找的标准中的术语是 odr-used 。
答案 1 :(得分:3)
std::max
通过引用而非值来获取其参数。将引用绑定到静态const需要一个实际的对象,而不仅仅是值。