开发者

Accessing X and Y in template class A like in template<template<int X, int Y> class> class A;

What is the correct syntax to use template parameters of a template class argument in another template class?

For example: How can I access X and Y of class Param in class Foo?

Program:

template < template < int, int > class X1>
struct Foo {
int foo() {
printf("ok%d %d\n", X1::X, X1::Y);
return 0;
}};

template < int X, int Y >
class Param {
int x,y;
public:
Param(){x=X; y=Y;}
void printParam(){
cout<<x<<" "<<y<<"\n";
}
};

int main() {
Param<10, 20> p;
p.printParam();
Foo< Param > tt;
tt.foo();
return 0;
}

As such for the above code, for the printf statement compiler complains:

In member function 'int Foo<X1>::foo()':
Line 4: error: 'template<int <anonymous>, int <anonymous> > class X1' used wit开发者_如何学Chout template parameters
compilation terminated due to -Wfatal-errors.


You can't. The template template parameter means that you take a template name without supplied template arguments.

Foo< Param > tt;

Here you can see that no values are supplied for Param. You'd take a template template parameter so that Foo itself could instantiate Params with any arguments it likes.

Example:

template < template < int, int > class X1>
struct Foo {

    X1<1, 2> member;

    X1<42, 100> foo();
};

template <int N, int P> struct A {};

template <int X, int Y> struct B {};

Foo<A> a_foo;  //has a member of type A<1, 2>, foo returns A<42, 100>
Foo<B> b_foo; //has a member of type B<1, 2>, foo returns B<42, 100>

But if you want your Foo to output those integers, it has to take real types, not templates. Secondly, the names of the template arguments (X and Y) are only meaningful where they are in scope. They are otherwise completely arbitrary identifiers. You can retrieve the values with simple metaprogramming:

#include <cstdio>

template <class T>
struct GetArguments;

//partial specialization to retrieve the int parameters of a T<int, int>
template <template <int, int> class T, int A, int B>
struct GetArguments<T<A, B> >
{
   enum {a = A, b = B};
};
//this specialization also illustrates another use of template template parameters:
//it is used to pick out types that are templates with two int arguments

template <class X1>
struct Foo {
  int foo() {
    printf("ok%d %d\n", GetArguments<X1>::a, GetArguments<X1>::b);
    return 0;
  }
};

template < int X, int Y >
class Param {
public:
   void print();
};

//this is to illustrate X and Y are not essential part of the Param template
//in this method definition I have chosen to call them something else
template <int First, int Second> 
void Param<First, Second>::print()
{
   printf("Param<%d, %d>\n", First, Second);
}

int main() {

    Foo< Param<10, 20> > tt;
    tt.foo();
    Param<10, 20> p;
    p.print();
    return 0;
}


This here is an example what could work as well:

template < typename X1>
struct Foo;

template < template < int, int > class X1, int X, int Y >
struct Foo< X1<X,Y> > {
    int foo() {
        printf("ok%d %d\n", X, Y);
        return 0;
    }
};

template < int X, int Y >
class Param {
    int x,y;
public:
    Param(){x=X; y=Y;}
    void printParam(){
        cout<<x<<" "<<y<<"\n";
    }
};

int main() {
    Param<10, 20> p;
    p.printParam();
    Foo< Param<30,40> > tt;
    tt.foo();
    return 0;
}


You can't take template parameters of a template class argument, since the argument is a template without parameters. You can do this instead:

template < typename X1 >
struct Foo;

template < template < int, int > class X1, int A, int B >
struct Foo< X1< A, B > >
{
    ... here you can use A and B directly, or X1< A, B >::X and X1< A, B >::Y ...
};

You specify the template to take a single type, and specialize it for the case of a template taking two int arguments. With that definition, you would use it like this:

Foo< Param< 0, 1 > > tt;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜