Undefined reference error when initializing unique_ptr with a static constant

When I try to use static constfor initialization unique_ptr, I get an "undefined reference" error. However, when I use a newpointer using the same constant, the symbol seems magical.

Here is a simple program that reproduces the error:

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;
}

I compiled the program using

g++ main.cpp -std=c++14

and got the following error.

/tmp/ccpJSQJS.o: In function `main':
main.cpp:(.text+0x51): undefined reference to `Outside_library::my_const'
collect2: error: ld returned 1 exit status

Can someone please help me understand why the constant is defined when using new, but not when using make_unique?

+4
source share
2 answers

C ++ has something known as a Single Definition Rule (ODR) :

, odr, ( ) , ; odr, , ; odr, . , odr, - ; , , .

:

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

"odr-use" Outside_library::my_const, std::make_unique() . odr, ( ). . cppreference:

  • x - ex odr, :

    • lvalue-to-rval x ,
    • x (.. x ), , x , e, lvalue-rvalue.

, Jarod42, constexpr const ( ). , , Outside_library::my_const.

g++ main.cpp -std=c++14 -lOutside_library
+3

make_unique () , odr- .

My_class(Outside_library::my_const) .

TU:

const int Outside_library::my_const;

constexpr ( ++ 11):

class Outside_library
{
public:
    static constexpr int my_const = 100;
};

a >

+3

Source: https://habr.com/ru/post/1692654/


All Articles