当我尝试使用 static const
来初始化 unique_ptr
时,我收到“ undefined reference ”错误。然而,当我新建
一个使用相同常量的指针时,符号似乎被神奇地定义了。
这是一个重现错误的简单程序:
Outside_library.h
class Outside_library
{
public:
static const int my_const = 100;
};
main.cpp
#include "Outside_library.h"
#include <iostream>
#include <memory>
class My_class
{
public:
My_class(int num)
{
m_num = num;
};
virtual ~My_class(){};
private:
int m_num;
};
int main(int, char* [])
{
My_class* p_class = new My_class(Outside_library::my_const);
delete p_class;
// ==== ERROR HERE: When I comment this line out, the program runs fine.
std::unique_ptr<My_class> p_unique
= std::make_unique<My_class>(Outside_library::my_const);
std::cout << "I made it through!" << std::endl;
return 0;
}
我编译程序使用
g++ main.cpp -std=c++14
并得到以下错误。
/tmp/ccpJSQJS.o: In function `main':
main.cpp:(.text+0x51): undefined reference to `Outside_library::my_const'
collect2: error: ld returned 1 exit status
谁能帮我理解为什么在使用 new
时定义常量,而在使用 make_unique
时却没有?
最佳答案
C++ 有一个叫做 One-Definition Rule (ODR) 的东西:
Informally, an object is odr-used if its value is read (unless it is a compile time constant) or written, its address is taken, or a reference is bound to it; a reference is odr-used if it is used and its referent is not known at compile time; and a function is odr-used if a function call to it is made or its address is taken. If an object, a reference or a function is odr-used, its definition must exist somewhere in the program; a violation of that is usually a link-time error.
链接站点给出了以下示例:
struct S {
static const int x = 0; // static data member
// a definition outside of class is required if it is odr-used
};
const int& f(const int& r);
int n = b ? (1, S::x) // S::x is not odr-used here
: f(S::x); // S::x is odr-used here: a definition is required
您的显式构造函数调用不会“使用”Outside_library::my_const
,但对 std::make_unique()
的调用会。当一个对象被 ODR 使用时,它必须只有一个定义(而不是声明)。您的示例只有一个声明。再次来自 cppreference :
a variable x in a potentially-evaluated expression ex is odr-used unless both of the following are true:
- applying lvalue-to-rvalue conversion to x yields a constant expression that doesn't invoke non-trivial functions
- either x is not an object (that is, x is a reference) or, if x is an object, it is one of the potential results of a larger expression e, where that larger expression is either a discarded-value expression or has the lvalue-to-rvalue conversion applied to it
Jarod42 建议的解决方案是使用 constexpr
而不是 const
(如果您可以控制“外部库”代码)。如果不这样做,则需要将程序链接到包含 Outside_library::my_const
的定义的库。
g++ main.cpp -std=c++14 -lOutside_library
关于c++ - 使用静态常量初始化 unique_ptr 时出现 undefined reference 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48428550/