ale*_*.tu 5 c++ definition one-definition-rule constexpr c++17
我有一个Config课程
// config.hpp
class Config {
public:
static constexpr int a = 1;
static constexpr int b = 1;
}
Run Code Online (Sandbox Code Playgroud)
并包含在main.cpp中
// main.cpp
#include "config.hpp"
int main () {
std::cout << Config::a << std::endl; // this is ok
std::shared_ptr<otherClass> stream = std::make_shared<otherClass>(
Config::a); // compile error
}
Run Code Online (Sandbox Code Playgroud)
和编译器说 undefined reference to Config::a
它在使用时起作用cout,但在shared_ptr构造函数中不起作用.
我不知道为什么会这样.
请注意,std :: make_shared通过引用获取参数,这会导致Config::a使用odr,因为它将绑定到引用参数,然后在命名空间范围内定义它是必需的(在C++ 17之前).
另一方面,std::cout << Config::a不会导致Config::a使用odr,因为std :: basic_ostream :: operator <<(int)按值获取参数,Config::a然后要求lvalue-to-rvalue转换请求copy-initialize参数因此Config::a,没有使用.
如果对象使用了odr,则其定义必须存在.您可以将定义(在实现文件中)添加为
constexpr int Config::a; // only necessary before C++17
Run Code Online (Sandbox Code Playgroud)
请注意,它不能有初始化程序.
由于C++ 17 constexpr静态数据成员是隐式内联的,因此不再需要这样的定义,因此您的代码在C++ 17中运行良好.
如果
static声明了数据成员constexpr,则它是隐式的inline,不需要在命名空间范围内重新声明.没有初始化程序(以前需要如上所示)的重新声明仍然允许,但已弃用.