Getting absurd errors in using template template arguments
I have been trying to create a templated class(Test2
) that takes 2 template arguments,Type1
and Type2
. It is known that the second argument would also be a templated class that takes 2 template arguments(TypeA
and TypeB
).
Now, for constructing an object of Test2
, I want the user to be able to use either of 2 types of constructors:
- One that takes objects of
Type1
andType2
. - One that takes objects of
Type1
,TypeA
andTypeB
.
I wrote the following code:
#include <iostream>
template<class TypeA, class TypeB>
struct Test
{
TypeA t1obj;
TypeB t2obj;
Test(const TypeA& t1, const TypeB& t2)
: t1obj(t1), t2obj(t2) {std::cout<<"Test::Type1, Type2\n";}
};
template<class Type1,
template<typename TypeX, typename TypeY> class Type2 >
struct Test2
{
Type1 t1obj;
Type2<typename TypeX, typename TypeY> t2obj; //Line 17
Test2(const Type1& t1,
const Type2<typename TypeX, typename TypeY>& t2) //Line 20
: t1obj(t1), t2obj(t2) { std::cout<<"Test2::Type1, Type2\n";}
Test2(const Type1& t1,
const TypeX& x,
const TypeY& y)
: t1obj(t1), t2obj(x,y) { std::cout<<"Test2::Type1, X, Y\n";}
};
int main()
{
Test<int, char> obj1(1,'a');
Test2<int, Test<int, char> > strangeobj1(10,obj1);
Test2<int, Test<int, char> 开发者_运维问答> strangeobj2(1,2,'b');
}
I have tried a lot but I get really absurd errors like:
wrong number of template arguments (1, should be 2)
on Line 17 and 20.
It doesn't work like that. Test<int, char>
is a full blown type, instead of a template. So you need type parameters
template<class Type1,
class Type2 >
struct Test2
{
Type1 t1obj;
Type2 t2obj; //Line 17
Test2(const Type1& t1,
const Type2& t2) //Line 20
: t1obj(t1), t2obj(t2) { std::cout<<"Test2::Type1, Type2\n";}
Test2(const Type1& t1,
const typename Type2::a_type& x,
const typename Type2::b_type& y)
: t1obj(t1), t2obj(x,y) { std::cout<<"Test2::Type1, X, Y\n";}
};
For getting TypeX
and TypeY
it's useful to export them so you can use them in Test2
as shown above.
template<class TypeA, class TypeB>
struct Test
{
typedef TypeA a_type;
typedef TypeB b_type;
// and using them, to show their meaning
a_type t1obj;
b_type t2obj;
Test(const a_type& t1, const b_type& t2)
: t1obj(t1), t2obj(t2) {std::cout<<"Test::Type1, Type2\n";}
};
Be sure to read Where to put the "template" and "typename" on dependent names to understand why and when to use typename
before type names like above.
There are several errors with this, but the main error seems to be that
Test2<int, Test<int, char> >
is not how you pass a template template parameter. This would be passed using
Test2<int, Test>
That is because Test
is a template but Test<int, char>
is a type (generated from that template.)
Type1
is a type, Type2
is a template. What exactly do you think TypeX
and TypeY
are defined? Inside the line template<typename TypeX, typename TypeY> class Type2 >
, they are ignored.
Here's one option:
#include <iostream>
template<class TypeA, class TypeB>
struct Test
{
TypeA t1obj;
TypeB t2obj;
Test(const TypeA& t1, const TypeB& t2)
: t1obj(t1), t2obj(t2) {std::cout<<"Test::Type1, Type2\n";}
};
template<class Type1, typename TypeX, typename TypeY,
template <typename TypeXi, typename TypeYi> class Type2>
struct Test2
{
Type1 t1obj;
Type2<typename TypeX, typename TypeY> t2obj; //Line 17
Test2(const Type1& t1,
const Type2<typename TypeX, typename TypeY>& t2) //Line 20
: t1obj(t1), t2obj(t2) { std::cout<<"Test2::Type1, Type2\n";}
Test2(const Type1& t1,
const TypeX& x,
const TypeY& y)
: t1obj(t1), t2obj(x,y) { std::cout<<"Test2::Type1, X, Y\n";}
};
int main()
{
Test<int, char> obj1(1,'a');
Test2<int, int, char, Test> strangeobj1(10,obj1);
Test2<int, int, char, Test> strangeobj2(1,2,'b');
}
Test<int, char>
is not a match for template<typename TypeX, typename TypeY> class Type2
The first one is an instantiation of a template class, it does not accept any parameters. The second one is a template class pattern accepting two parameters.
精彩评论