Reputation: 588
I have a function taking, as an argument, a template class with multiple parameters (see 'func2' in the following code). I'd like the function to be able to take as argument a class inheriting from the agument type, and automatically resolve template types by upcasting. In the following example, it's ok for function 'func1', but it's apparently not possible straightforwardly when argument is a multiple template class as for function 'func2'.
The error message states: "Candidate template ignored: substitution failure : template template argument has different template parameters than its corresponding template template parameter" I understand (and kind of agree) with the message. But this is the same case for 'func1', and it's working fine.
So my question is, is there a way I can treat variable 'd' as type 'C' by automatic upcasting when using a function ? And if so, how ? I'm using Xcode 5.1.1, clang-503.0.40. and C++11 option. Thanks
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;
}
Upvotes: 2
Views: 767
Reputation: 588
Ok so the best option I found is as follow. The idea is to make 'D' believe it's a multiple template class, but in fact one of the template parameters is only meant to be a specific type (int). This way, 'D2' is sort of both a one template class and two template class. There's still one partial specialization when defining template class D , but it's actually only the normal definition of class 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;
}
Upvotes: 0
Reputation: 40887
No, there's no way to do what you're trying to do.
You can use an alias though, assuming your compiler supports them:
template < typename T >
using D = C<T,int>;
I believe that should match your function template just fine.
If you're trying to have D have different behavior then you'd create a partial specialization of C.
Upvotes: 1