嗨,我在选择具有明确特化的模板化类的正确版本时遇到问题.我想要使用用于专门化的类的派生类来选择特化.场景是:
#include <stdio.h> class A {}; class B: public A {}; template<typename T> class Foo { public: int FooBar(void) { return 10; } }; // Explicit specialization for A template<> int Foo< A >::FooBar( void ) { return 20; } void main( void) { Foo<B> fooB; // This prints out 10 instead of wanted 20 ie compiler selects the general version printf("%d",fooB.FooBar() ); }
正如我在评论中所说的那样,我希望看到20被打印出来,因为B是从A派生出来的,而10则是打印出来的.如何在不诉诸为每个派生类编写专门化的情况下调用专门化(我的实际场景有很多派生类型).
解决方法
—编辑:新的答案让我们让原始方法更易于维护.
所有重要的选择都可以在Foo的定义中找到.它应该易于维护.
所有重要的选择都可以在Foo的定义中找到.它应该易于维护.
#include <boost/mpl/if.hpp> #include <boost/type_traits/is_base_of.hpp> #include <iostream> class A {}; class B: public A {}; class C{}; class D : public C{}; class E{}; struct DefaultMethod { static int fooBar() { return 10; } }; struct Method1 { static int fooBar() { return 20; } }; struct Method2 { static int fooBar() { return 30; } }; template<typename T,typename BaseClass,typename Choice1,typename OtherChoice> struct IfDerivesFrom : boost::mpl::if_< typename boost::is_base_of<BaseClass,T>::type,Choice1,OtherChoice>::type { }; template<typename T> struct Foo : IfDerivesFrom<T,A,Method1,IfDerivesFrom<T,C,Method2,DefaultMethod> > { }; int main() { std::cout << Foo<A>::fooBar() << std::endl; std::cout << Foo<B>::fooBar() << std::endl; std::cout << Foo<C>::fooBar() << std::endl; std::cout << Foo<D>::fooBar() << std::endl; std::cout << Foo<E>::fooBar() << std::endl; return 0; }
—原始答案
如果您可以使用boost,您可以执行以下操作:
#include <boost/type_traits/is_base_of.hpp> template<bool b> class FooHelper { int FooBar(); }; template<> FooHelper<true>::FooBar(){ return 20;} template<> FooHelper<false>::FooBar(){ return 10;} template<typename T> class Foo { public: int FooBar(void) { return FooHelper<boost::is_base_of<A,T>::type::value>(); } };