次の例を検討してください。
#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;
}
この問題を解決するにはどうすればよいですか ( Derived
typedef がBase
クラスから不明)。
編集:非常に単純なトリックを見つけました。以下が機能し、以前のバージョンが機能しない理由を誰かに説明してもらえますか? このトリックは標準の C++11 で問題ありませんか、それともコンパイラの動作方法 (ここでは 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;
}