c++ - 使用静态常量初始化 unique_ptr 时出现 undefined reference 错误

标签 c++ c++14 smart-pointers

当我尝试使用 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 :

  1. 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/

相关文章:

c++ - 保留 std::initializer_list 的拷贝是否安全?这是什么道理?

C++如何使用未初始化的智能指针

c++ - 为什么两个迭代器在循环中分开?

c++ - OpenGL-点云的变色方案

c++ - 在模板参数列表中使用 sizeof... 时为 "too few template arguments"(MSVC 2017)

c++ - 自定义智能指针和多项式比较运算符

c++ - 使用shared_ptr来获得唯一的所有权(某种程度)——这是一个好的做法吗?

C++ std::chrono::high_resolution_clock time_since_epoch 返回的数字太小。如何获得自 1970 年以来以微秒为单位的正确时间?

java - 用于语音效果的环形调制器

c++ - std::vector of movable-only lambdas,这可能吗?