c++ - Template and constexpr deduction at compiletime dependent on compiler and optimization flags -


the following question condensed larger code. therefore expressions seem overkill or unnecessary, crucial original code.

consider having struct, contains compile time constants , simple container class:

template<typename t> struct const {     static constexpr t one()     {          return static_cast<t>( 1 );     } };  template<typename t> class container { public:     using value_type = t;     t value; }; 

now having template function, has "specialization" types offering value_type:

template<typename t> void dosomething( const typename t::value_type& rhs ) {} 

now expect, should work:

template<typename t> class tester { public:     static constexpr t 1 = const<t>::one();      void test()     {         dosomething<container<t>>( 1 );     } }; 

the interesting point is, compiler not complain definition of tester<t>::one, usage. further not complain, if use const<t>::one() or static_cast<t>( 1 ) instead of one in function call. however, both should known @ compile time , therefore usable. first question is: compiler in cases, works, calculations @ compile time?

i checked g++-5, g++-6 , clang-3.8 compiler using -std=c++14 flag. complain

undefined reference `tester<int>::one' 

although used features are, far know, in standard , should therefore supported. interestingly compilation successful add optimization flag o1, o2 or o3. second question is: there strategy of compiler doing compile time calculations only, if optimization flags active? have expected @ least things, declared compile time constant always deduced!

the last part of question covers nvidia nvcc compiler (version 8.0). can pass -std=c++11 it, may features not covered. however, using 1 of host compiler above, complains

error: identifier "tester<int> ::one" undefined in device code 

even if optimization flag passed! same problem above, while questions above more academical (because can use optimization flag rid of problem), here problem (concerning fact not know, done @ compile time when use workarounds mentioned above - , uglier). third question is: there way of using optimizations in device code?

the following code mwe pure host , nvcc compiler:

#include <iostream> #include <cstdlib>  #ifdef __cudacc__     #define hd __host__ __device__ #else     #define hd #endif   template<typename t> struct const {     hd static constexpr t one()     {         return static_cast<t>( 1 );     } };   template<typename t> class container { public:     using value_type = t;     t value; };   template<typename t> hd void dosomething( const typename t::value_type& rhs ) {}   template<typename t> class tester { public:     static constexpr t 1 = const<t>::one();      hd void test()     {         dosomething<container<t>>( 1 );         // dosomething<container<t>>( static_cast<t>( 1 ) );         // dosomething<container<t>>( const<t>::one() );     } };   int main() {     using t = int;      tester<t> tester;     tester.test();      return exit_success; } 

thanks in advance!

the difference between this:

dosomething<container<t>>( 1 ); 

as opposed these two:

dosomething<container<t>>( static_cast<t>( 1 ) ); dosomething<container<t>>( const<t>::one() ); 

is in first case you're binding reference directly one , others not. more specifically, odr-using one in first case not other two. when odr-use entity, needs definition, , one declared not defined.

you need define it:

template<typename t> class tester { public:     // declaration     static constexpr t 1 = const<t>::one();     // .. };  // definition template <typename t> constexpr t tester<t>::one; 

Comments

Popular posts from this blog

unity3d - Rotate an object to face an opposite direction -

angular - Is it possible to get native element for formControl? -

javascript - Why jQuery Select box change event is now working? -