Доступ к X и Y в шаблонном классе A, как в шаблоне <template <int X, int Y> class> class A; - PullRequest
3 голосов
/ 12 октября 2011

Каков правильный синтаксис для использования параметров шаблона аргумента класса шаблона в другом классе шаблона?

Например: как я могу получить доступ к X и Y класса Param в классе Foo?

Программа:

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;
}

Как таковая для кода выше, для printfКомпилятор операторов жалуется:

In member function 'int Foo<X1>::foo()':
Line 4: error: 'template<int <anonymous>, int <anonymous> > class X1' used without template parameters
compilation terminated due to -Wfatal-errors.

Ответы [ 3 ]

6 голосов
/ 12 октября 2011

Вы не можете. Параметр шаблона шаблона означает, что вы берете имя шаблона без предоставленных аргументов шаблона .

Foo< Param > tt;

Здесь вы можете видеть, что для Param не указаны значения. Вы бы взяли параметр шаблона template, чтобы сам Foo мог создать экземпляр Params с любыми аргументами, которые ему нравятся.

Пример:

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>

Но если вы хотите, чтобы ваш Foo выводил эти целые числа, он должен принимать реальные типы, а не шаблоны. Во-вторых, имена аргументов шаблона (X и Y) имеют смысл только там, где они находятся в области видимости. В остальном это совершенно произвольные идентификаторы. Вы можете получить значения с помощью простого метапрограммирования:

#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;
}
1 голос
/ 12 октября 2011

Вот пример, который также может работать:

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;
}
0 голосов
/ 12 октября 2011

Вы не можете принимать параметры шаблона аргумента класса шаблона, так как аргумент является шаблоном без параметров.Вместо этого вы можете сделать это:

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 ...
};

Вы указываете шаблон для одного типа и специализируете его для случая шаблона, принимающего два int аргумента.С этим определением вы бы использовали его так:

Foo< Param< 0, 1 > > tt;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...