shared_ptr中对const int的未定义引用

undefined reference to const int within shared_ptr

本文关键字:未定义 引用 int const ptr 中对 shared      更新时间:2023-10-16

我有一个配置类

// config.hpp
class Config {
public:
static constexpr int a = 1;
static constexpr int b = 1;
}

并包含在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
}

编译器说undefined reference to Config::a

它在使用cout时起作用,但在shared_ptr构造函数内不起作用。

我不知道为什么会发生这种事。

请注意,std::make_shared通过引用获取参数,这会导致Config::a被odr使用,因为它将被绑定到引用参数,那么它在命名空间范围内的定义是必需的(在C++17之前)。

另一方面,std::cout << Config::a不会导致使用Config::a,因为std::basic_stream::operator<lt;(int)按值取参数,然后Config::a进行左值到右值的转换,请求复制初始化参数,因此不使用Config::a

如果一个对象是odr使用的,那么它的定义必须存在。您可以将定义(在实现文件中)添加为

constexpr int Config::a; // only necessary before C++17

请注意,它不能有初始值设定项。

实时

由于C++17constexpr静态数据成员是隐式内联的,因此不再需要这样的定义,因此您的代码在C++17中运行良好。

如果static数据成员被声明为constexpr,则它是隐式inline,不需要在命名空间范围内重新声明。这种不带初始值设定项的重新声明(以前如上所示是必需的)仍然是允许的,但已被弃用。

实时

您的a是私有的,或者是public:需要对其进行预处理,或者使该类成为一个结构以获得默认的public。但这是在C++14下编译的https://godbolt.org/g/tS4M1Z

#include <iostream>
#include <memory>
struct Config {
static constexpr int a = 1;
static constexpr int b = 1;
};
struct otherClass {
otherClass( int c ) { }
};
int main () {
std::cout << Config::a << std::endl; // this is ok
std::shared_ptr<otherClass> stream = std::make_shared<otherClass>( Config::a ); // compile error
}