Если вы уже добавили typename
в соответствии с предложением Nawaz.
Проблема точно объясняется в сообщении об ошибке, с которым вы сталкиваетесь: «параметр шаблона не выводится при частичной специализации B<T>::type*
. Проблема в том, чтоB<T>::type
и T
абсолютно одинаковы для всех типов T
. Рассмотрим следующий пример:
class MyClass1 {};
typedef typename B<MyClass>::type MyClass2; //(*)
X<MyClass*> obj1;
X<MyClass2*> obj2;
Результатом строки (*)
является тип MyClass2, который по существу равен MyClass1
.Итак, obj1
и obj2
должны быть объектами одного класса. Теперь, какую версию шаблона X
они должны использовать?
Если вы ожидаете специализированную версию X
, скажите мнеесли ответ должен быть таким же, если строка (*)
удалена (и, очевидно, obj2
). Тем не менее obj1
должна быть специализированной версией X
, так как строка (*)
не имеет к этому никакого отношения.
Но теперь мы ожидаем, что компилятор обнаружит, что некоторый тип может быть потенциально объявлен как B<T>::type
, хотя мы никогда этого не делаем. Мы ожидаем, что компилятор проверит все возможные экземпляры шаблонаs, чтобы проверить, нет ли странного typedef в одном из них.
Надеюсь, это проясняет, почему такая специализация не может быть обработана компилятором.
Альтернатива, которая можетhelp
Я полагаю, что ваша проблема может быть решена путем создания класса черт для явного обозначения типов, которые должны обрабатываться особым образом.Примерно так:
template <bool v>
struct boolean_value {
static const bool value=v;
};
template <typename T>
struct is_my_interesting_type : public boolean_value<false> {};
class MyClass {
...
};
template <>
struct is_my_interesting_type<MyClass> : public boolean_value<true> {};
template <typename T, bool special>
class InternalX {
... //generic version of your template X
};
template <typename T>
class InternalX<T,true> {
... //special version of your template X
};
template <typename T>
class X : public InternalX<T,is_my_interesting_type<T>::value> {};
Также вам может быть интересно, как это делается в библиотеке буста, в частности Boost.Type_Traits