Consider the following example:
#include <iostream> #include <iostream> #include <type_traits> template<typename Type, template<typename> class Crtp> class Base { public: typedef int value; // f1: OK // Expected result: casts 4.2 to Base<Type, Crtp>::value value f1() {return 4.2;} // f2: NOT OK // Expected result: casts 4.2 to Crtp<Type>::value // But f2 does not compile: no type named 'value' // in 'class Derived<double>' typename Crtp<Type>::value f2() {return 4.2;} }; template<typename Type> class Derived : public Base<Type, Derived> { public: typedef Type value; }; int main() { Derived<double> a; std::cout<<a.f1()<<std::endl; std::cout<<a.f2()<<std::endl; return 0; }
How to solve this problem ( Derived typedef is unknown from the Base class)?
EDIT: I found a very simple trick. Can someone explain to me why the following works and the previous version does not work? Is this trick normally standard C ++ 11 or does it work because of how the compiler works (here g ++ 4.7.1)?
#include <iostream> #include <iostream> #include <type_traits> template<typename Type, template<typename> class Crtp> class Base { public: typedef int value; value f1() {return 4.2;} template<typename T = Crtp<Type>> typename T::value f2() {return 4.2;} }; template<typename Type> class Derived : public Base<Type, Derived> { public: typedef Type value; }; int main() { Derived<double> a; std::cout<<a.f1()<<std::endl; std::cout<<a.f2()<<std::endl; return 0; }
source share