Undefined reference to const int inside shared_ptr

I have a Config class

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

and include in 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 } 

and the compiler said undefined reference to Config::a

and it works when using cout , but does not work in the shared_ptr constructor.

I have no idea why this is happening.

+5
source share
2 answers

Note that std :: make_shared takes a parameter by reference, which leads to Config::a odr-used , since it will be bound to the reference parameter, then it needs to be defined in the namespace area (before C ++ 17).

On the other hand, std::cout << Config::a will not use Config::a to use odr, because std :: basic_ostream :: operator <<<<<<<<<<<<<<<<<< <; (int) takes a parameter by value, Config::a then undergoes the lvalue-to-r transformation requested to copy-initialize the parameter, so Config::a not used odr.

If an object is used by odr, its definition must exist. You can add a definition (to the implementation file) as

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

Note that it cannot have an initializer.

Live

Since the C ++ 17 constexpr static data element is implicitly embedded, then such a definition is not required again, so your code works well from C ++ 17.

If the static data member is declared constexpr , it is implicitly inline and does not need to be updated in the namespace scope. This update without an initializer (previously required as shown above) is still allowed, but is deprecated.

Live

+7
source

Your a is private and either public: it needs to execute it or make the struct class accessible by default. But this compiles under 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 } 
+1
source

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


All Articles