今天我在 class 声明中用 static const int 定义一个整形常量,之后在别的地方用它,最后链接失败。最后我只好改用 enum 来定义它。
Bjarne Stroustrup 的 FAQ 里面就建议使用 enum 的方法。[1]
GCC 对这个问题的说明 [2] 是,在 class 声明中的 static const int 只是声明,而不是定义,编译时可能会内联这些常量,但是如果要在需要传引用的地方用它,仍然需要定义出来。
另外如果把 const 改为 constexpr, 在 C++ 14 (Clang 默认) 和 C++ 17 (GCC 默认) 标准中还有区别,C++ 17 会认为 static constexpr 是隐式内联的,每个翻译单元会有一个内联定义,而 C++ 14 则没有。所以如果把 const 改为 constexpr, 使用 C++ 17 编译器会链接成功,使用 C++ 14 编译器会链接失败。
[1] http://www.stroustrup.com/bs_faq2.html#in-class
[2] https://gcc.gnu.org/wiki/VerboseDiagnost...definition
代码:
#include <vector>
#include <iostream>
class A
{
std::vector<int> v;
public:
static const int num_A = 5;
A() { v.emplace_back(num_A); }
};
int main()
{
A a;
std::cout << A::num_A << std::endl;
}
Bjarne Stroustrup 的 FAQ 里面就建议使用 enum 的方法。[1]
GCC 对这个问题的说明 [2] 是,在 class 声明中的 static const int 只是声明,而不是定义,编译时可能会内联这些常量,但是如果要在需要传引用的地方用它,仍然需要定义出来。
另外如果把 const 改为 constexpr, 在 C++ 14 (Clang 默认) 和 C++ 17 (GCC 默认) 标准中还有区别,C++ 17 会认为 static constexpr 是隐式内联的,每个翻译单元会有一个内联定义,而 C++ 14 则没有。所以如果把 const 改为 constexpr, 使用 C++ 17 编译器会链接成功,使用 C++ 14 编译器会链接失败。
[1] http://www.stroustrup.com/bs_faq2.html#in-class
[2] https://gcc.gnu.org/wiki/VerboseDiagnost...definition