如何在其子类中使用类模板特化?

时间:2013-10-05 05:34:09

标签: c++ templates

我有一个类模板如下:

template<class T>
class A;

TPair<T1, T2>时,我会将其专门化。

template<class T1, class T2>
class A<Pair<T1, T2>>;

我有一个派生于

的课程
class D : public Pair<int, char>
{};

当我使用A<D>时,我希望它使用专门版本但不支持。我有很多来自Pair或其他专业版的类。怎么自动完成?

2 个答案:

答案 0 :(得分:1)

它不起作用的原因是因为你把它专门用于对,而不是从继承对的类(BTW通常是从stdlib类继承的坏主意)。您可以将其专门用于D

template<class T>                                                                  
struct A {                                                                         
    A(){cout << "not special\n";}                                                  
};                                                                                 

template<class T1, class T2>                                                       
struct A<pair<T1, T2>> {                                                           
    A(){cout << "special\n";}                                                      
};                                                                                 

struct D : public pair<int, char>                                                  
{};                                                                                

template<>                                                                         
struct A<D> {                                                                      
    A(){cout << "special D\n";}                                                    
};                                                                                 

int main() {                                                                       
    A<D> a;                                                                        
    return 0;                                                                      
}  

输出special D

您也可以使用std::is_base_of,但这会很痛苦,我建议不要这样做。如果你这样做了,你就可以有另外一个这样的课程

template <typename T, bool B>
struct helper;                                                                         

template <typename T>
struct helper<T,true>;

template <typename T>
struct helper<T,true>;

然后你可以在第一个类中创建该类,如

template<class T>                                                                  
struct A {
    helper<T,is_base_of<pair<int,char>,T>::value> h;
};

那应该让你开始我会让你弄明白其余:)。

这是一个只有一个类的更简洁的版本。

template<class T,bool B = is_base_of<pair<int,char>,T>::value>                     
struct A;                                                                          

template<class T>                                                                  
struct A<T,true> {                                                                 
    A(){cout << "special\n";}                                                      
};                                                                                 

struct D : public pair<int, char>                                                  
{};                                                                                

template<class T>                                                                  
struct A<T,false> {                                                                
    A(){cout << "not special\n";}                                                  
};                                                                                 

int main() {                                                                       
    A<D> a;                                                                        
    A<int> b;                                                                      
    return 0;                                                                      
}  

答案 1 :(得分:1)

“永远不会从std类型派生,它们并不意味着派生。派生可能会导致UB”

Dpair<int,char>的类型不同(尽管从中派生)。模板参数推导不考虑类型之间的转换能力。它只匹配类型。

现在,在您要调用专用版本的情况下,您可以使用标记分发和帮助程序。

以下代码可能会对您有所帮助:

template<class T>                   //Primary class template
class A
{//impl..};


template<class T1, class T2>       //explicit specialization
class A<pair<T1, T2>>
{
public:
A(){std::cout << "A<pair>\n";}
};


template<typename T1,typename T2, bool b>  //type selector utility, dispatched to this
struct AP{typedef A<T1> type;};            // type if passed type is not a 
                                           //derived class of pair.


template<typename T1,typename T2>
struct AP<T1,T2,std::true_type::value>
{
    typedef A<pair<T1,T2>> type;    //only if passed type is derived from pair
};



class D : public pair<int, char>
{};                                    //type derived from pair


class E{};                             //some other type

template<typename pair,typename t>      //helper class to do the dirty job
struct APH
{
    using fsttyp = typename pair::first_type;
    using sndtyp = typename pair::second_type;
    typedef typename AP<fsttyp,sndtyp,is_base_of<pair,t>::value>::type type;
};            

int main()
{

    APH<pair<int,char>,D>::type a;// a is of A<pair<int,char>> type
    APH<pair<int,char>,E>::type a;// a is of A<E> type
    return 0;
}