c – 根据派生类型选择类的显式特化

前端之家收集整理的这篇文章主要介绍了c – 根据派生类型选择类的显式特化前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
嗨,我在选择具有明确特化的模板化类的正确版本时遇到问题.我想要使​​用用于专门化的类的派生类来选择特化.场景是:
#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的定义中找到.它应该易于维护.
#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>(); }
};

猜你在找的C&C++相关文章