Reputation: 1125
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:
Type1
and Type2
.Type1
, TypeA
and TypeB
. 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.
Upvotes: 1
Views: 265
Reputation: 507403
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.
Upvotes: 6
Reputation: 283921
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.
Upvotes: 0
Reputation: 224189
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.)
Upvotes: 1
Reputation: 15328
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');
}
Upvotes: 0
Reputation: 263360
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.
Upvotes: 0