Можно ли получить доступ к параметру шаблона вне шаблона без определения типа? - PullRequest
8 голосов
/ 12 сентября 2010

Простой пример:

template<typename _X> // this template parameter should be usable outside!
struct Small {
   typedef _X X; // this is tedious!
   X foo;
};

template<typename SomeSmall>
struct Big {
   typedef typename SomeSmall::X X; // want to use X here!
   SomeSmall bar;
   X toe;
};

Есть ли способ получить доступ к параметру шаблона X из Small без использования typedef в классе Small?

Ответы [ 2 ]

8 голосов
/ 12 сентября 2010

Да, определите второй шаблон «получателя» с частичной специализацией.

template< typename >
struct get_Small_X; // base template is incomplete, invalid

template< typename X > // only specializations exist
struct get_Small_X< Small< X > > {
    typedef X type;
};

Теперь вместо Small<X>::X у вас есть typename get_Small_X< Small<X> >::type.

Кстати, _Xявляется зарезервированным идентификатором, поэтому его не следует использовать ни для чего.X_ - лучший выбор.


Дополнительная тема: самоанализ шаблона.

Пока я думаю об этом, вам не нужно определять это отдельно для каждого шаблона.Один главный шаблон должен это делать.

Это компилируется в Comeau, я знаю, что есть правила для сопоставления аргументов шаблона шаблона, но я думаю, что все в порядке… Аргументы шаблона шаблона запрещены в шаблоне master в частичной специализации.

template< typename >
struct get_first_type_argument;

template< template< typename > class T, typename X >
struct get_first_type_argument< T< X > > {
    typedef X type;
};

template< typename X >
struct simple;

get_first_type_argument< simple< int > >::type q = 5;

Это работает только с "унарными" шаблонами, но может быть адаптировано в C ++ 0x для общего случая.

4 голосов
/ 12 сентября 2010

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

// "typename X" is a template type parameter. It accepts a type.
// "template <typename> class SomeSmall" is a template template parameter.
// It accepts a template that accepts a single type parameter.
template<typename X, template <typename> class SomeSmall> 
struct Big {
   SomeSmall<X> bar; // We pass X to the SomeSmall template.
   X toe; // X is available to this template.
}; 

// Usage example:

template<typename X>
struct Small { 
   X foo; 
};

struct MyType {};

// The foo member in Small will be of type MyType.
Big<MyType, Small> big;
...