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 definitionconstexpr
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
Post a Comment