我有一个类模板如下:
template<class T>
class A;
当T
是Pair<T1, T2>
时,我会将其专门化。
template<class T1, class T2>
class A<Pair<T1, T2>>;
我有一个派生于
的课程class D : public Pair<int, char>
{};
当我使用A<D>
时,我希望它使用专门版本但不支持。我有很多来自Pair或其他专业版的类。怎么自动完成?
答案 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”
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;
}