1

我有一个类模板如下:

template<class T>
class A;

什么时候T是 a Pair<T1, T2>,我专门研究它。

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

我有一个派生自 Pair 的类

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

当我使用时A<D>,我希望它使用专门的版本,但它没有。我有许多派生自 Pair 或其他专门版本的类。如何自动完成?

4

2 回答 2

1

它不起作用的原因是因为您将它专门用于 pair,而不是从 pair 继承的类(顺便说一句,从 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;                                                                      
}  
于 2013-10-05T05:55:39.530 回答
1

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

D是一种不同的类型pair<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;
}
于 2013-10-05T06:55:02.020 回答