c ++函数参数,自动向上转换多个模板化类

时间:2014-10-14 09:52:45

标签: c++ function templates arguments upcasting

我有一个函数,作为一个参数,一个带有多个参数的模板类(参见下面代码中的'func2')。我希望该函数能够将继承自agument类型的类作为参数,并通过向上转换自动解析模板类型。在下面的例子中,函数'func1'没问题,但是当参数是多模板类和函数'func2'时,它显然是不可能的。

错误消息指出:“忽略了候选模板:替换失败:模板模板参数具有与其对应的模板模板参数不同的模板参数” 我理解(并且有点同意)这个消息。但这与'func1'的情况相同,而且工作正常。

所以我的问题是,有没有办法在使用函数时通过自动向上转换将变量'd'视为'C'类型?如果是这样,怎么样? 我正在使用Xcode 5.1.1,clang-503.0.40。和C ++ 11选项。感谢

template <class T1>
class A {};

class B : public A<int> {};

template <template <class T1> class T, class T1 >
void func1(T<T1> _arg) {}

template <class T1, class T2>
class C {};

template <class T1>
class D : public C<T1,int> {};

template <template <class T1, class T2> class T, class T1, class T2>
void func2(T<T1,T2> _arg) {}


int main() {
    A<int> a;
    B b;
    func1(a);//works
    func1(b);//works, T1 is resolved

    C<float,int> c;
    D<float> d;
    func2(c);//works
    func2(d);//doesn't work,compilation error message: "Candidate template ignored: substitution failure : template template argument has different template parameters than its corresponding template template parameter"

    return 0;
}

2 个答案:

答案 0 :(得分:1)

不,没有办法做你想做的事。

您可以使用别名,假设您的编译器支持它们:

template < typename T >
using D = C<T,int>;

我相信这应该与您的功能模板完全匹配。

如果您尝试让D有不同的行为,那么您将创建C的部分特化。

答案 1 :(得分:0)

好的,我找到的最佳选择如下。这个想法是让'D'相信它是一个多模板类,但实际上其中一个模板参数只是一个特定的类型(int)。这样,'D2'既可以是一个模板类,也可以是两个模板类。在定义模板类D时仍然有一个部分特化,但它实际上只是D类的正常定义。

template <class T1, class T2>
class C {};

template <class T1, class T2=int>
class D;

template <class T1>
class D<T1,int> : public C<T1,int> {};

template <typename T1>
using D2 = D<T1>;

template <template <class T1, class T2> class T, class T1, class T2>
void func2(T<T1,T2> _arg) {}

int main()
{
    C<float,int> c;
    D2<float> d;
    func2(c);//works
    func2(d);//works

    //instantiation tests:
    D<float> test1;//works -> normal
    D<float, int> test2;//works -> not ideal but well ok
    D<float, float> test3;//doesn't work -> also normal. States: "Implicit instantiation of undefined template 'D<float, float>' "

    return 0;
}