c++ - Undefined reference with g++4.7.3 and g++4.8? -


consider code :

#include <iostream> #include <array>  template <typename type> struct constant {     constexpr constant(const type source) : _data({{source}}) {;}     constexpr constant(const std::array<type, 1> source) : _data(source) {;}     constexpr constant<type> operator()() const {return _data;}     constexpr operator type() const {return _data[0];}     const std::array<type, 1> _data;     static constexpr constant<type> pi = 3.1415926535897932384626433832795028841971693993751058209749445l; };  int main(int argc, char* argv[]) {     std::cout<<constant<double>::pi()<<std::endl;     return 0; } 

i compiler error g++4.7.3 , g++4.8.0 (which undefined reference pi (sorry it's in french)) :

/tmp/cctdvpfq.o: dans la fonction « main »: main.cpp:(.text.startup+0xd): référence indéfinie vers « constant<double>::pi » collect2: erreur: ld retourné 1 code d'état d'exécution 

as system fresh install (first time g++4.7.3 , g++4.8.0), not know whether comes system configuration or compiler. if comes compiler, problem ?

edit: , why working ? (version no array)

#include <iostream> #include <array>  template <typename type> struct constant {     constexpr constant(const type source) : _data(source) {;}     constexpr constant<type> operator()() const {return _data;}     constexpr operator type() const {return _data;}     const type _data;     static constexpr constant<type> pi = 3.1415926535897932384626433832795028841971693993751058209749445l; };  int main(int argc, char* argv[]) {     std::cout<<constant<double>::pi()<<std::endl;     return 0; } 

you avoid invoking call operator on pi, not odr-used program, , compiler can treat pi value can inlined, not requiring definition static data member:

std::cout << constant<double>::pi << std::endl; //                             ^^ 

alternatively, keep invoking pi's call operator, , provide definition of static data member @ namespace scope, , use call operator of constant<double> in original code:

template <typename type> struct constant {     // ...     static constexpr constant<type> pi = /* ... */; };  template<typename type> constexpr constant<type> constant<type>::pi; 

per paragraph 9.4.2/3 of c++11 standard:

if non-volatile const static data member of integral or enumeration type, declaration in class definition can specify brace-or-equal-initializer in every initializer-clause assignment-expression constant expression (5.19). static data member of literal type can declared in class definition constexpr specifier; if so, declaration shall specify brace-or-equal-initializer in every initializer-clause assignment-expression constant expression. [ note: in both these cases, member may appear in constant expressions. —end note ] the member shall still defined in namespace scope if odr-used (3.2) in program , namespace scope definition shall not contain initializer.


Comments

Popular posts from this blog

linux - xterm copying to CLIPBOARD using copy-selection causes automatic updating of CLIPBOARD upon mouse selection -

c++ - qgraphicsview horizontal scrolling always has a vertical delta -