我知道 C++ 标准说(第 9.4.2 节第 4 段)整数或枚举类型的静态成员变量可以在类内部提供初始化程序,但这需要在类外部定义该成员(在编译单元中)。即,您需要执行以下操作:
class A
{
public:
static const int X = 10;
};
// this is required by the standard
const int A::X;
我已经看到(并且我已经看到它在其他地方说过)某些编译器会让您在没有类外定义的情况下逃脱。这适用于 OS X 上的 gcc 4.2.1:
#include <iostream>
class A
{
public:
static const int X = 10;
};
int main(int argc, char** argv)
{
std::cout << A::X << std::endl;
return 0;
}
我最近遇到了一个错误,有人这样做了,但是他们在模板函数中使用了成员变量(std::max
准确地说),它不会编译,抱怨未定义的符号 A::XIe,这不起作用:
#include <iostream>
#include <algorithm>
class A
{
public:
static const int X = 10;
};
int main(int argc, char** argv)
{
std::cout << std::max(1, A::X) << std::endl;
return 0;
}
添加回类外定义使其工作。
这是一个学术问题,但我想知道为什么会这样。尤其是如果我们用静态函数(static const int X = 10;
变成static int X()
,A::X
变成A::X()
)替换静态成员变量,那么它将在没有类外定义的情况下编译。我提到模板的原因是因为std::max
是模板化的,而其他模板化函数重现了相同的行为。它可能与模板没有具体关系,但我想了解为什么模板会导致它们的行为。我认为这一定与模板和静态成员的编译/实现方式有关?
PS - 我在github上发布了一些最小的代码