Сначала измените значение typename
на class
, §14.1 [temp.param] p1
:
параметр типа:
- класс идентификатор opt
- класс идентификатор opt = идентификатор типа
- имя типа идентификатор opt
- имя типа идентификатор opt = идентификатор типа
- шаблон <<em>список параметров шаблона > класс идентификатор опт
- шаблон <<em> список параметров шаблона > class идентификатор opt = id-выражение
Далее выполните частичную специализацию:
template<class T>
class Check;
template< // not 'typename' vvvvv
template<typename,typename> class C,
typename A, typename B
>
struct Check<C<A,B> >{
// ...
};
Тем не менее, вы все равно не можете передать только Hello
в шаблон, потому что, хотя Hello
происходит от TemplatedClass
, преобразование типов недопустимо для параметров шаблона:
Check<Hello> c; // nope, 'Hello' is not a template
Вы можете добавить следующую typedef к классу Hello
:
class Hello
: TemplatedClass<int,float>
{
public:
typedef TemplatedClass<int,float> base_type;
};
И сделать:
Проверьте c;// ОК Но тогда параметр C
в Check
будет template TemplatedClass
, а не Hello
.К сожалению, нет способа достичь этого напрямую.Одним из решений является передача производного типа либо в качестве дополнительного параметра шаблона, либо просто передача производного типа в качестве единственного параметра и внутреннее извлечение типа:
template<class T>
class CheckInternal;
template<
template<typename,typename> class C,
typename A, typename B
>
class CheckInternal<C<A,B> >{
public:
typedef A type_A;
typedef B type_B;
};
template<class T>
class Check{
typedef typename T::base_type T_base_type;
typedef typename CheckInternal<T_base_type>::type_A type_A;
typedef typename CheckInternal<T_base_type>::type_B type_B;
void foo(type_A a, type_B b){
// ...
}
};
// usage:
C<Hello> c; // OK!