Если у нас есть Base
а также Derived
классы
class Base
{};
class Derived : public Base
{};
и шаблон класса
template <class T, class Enabler=void>
class Partialy
{
public:
void say()
{
std::cout << "Partialy Default" << std::endl;
}
};
Мы можем написать частичную специализацию следующим образом:
template <class T>
class Partialy<T, typename std::enable_if<std::is_base_of< Base, T >::value>::type>
{
public:
void say()
{
std::cout << "Partialy special" << std::endl;
}
};
Пример 1 будет работать хорошо (Полный код: http://ideone.com/4FyrD )
Если бы я только сделал Base
шаблон класса один:
template <class T>
class BaseTpl
{};
class DerivedTpl : public BaseTpl<int>
{};
Следующая частичная специализация не работает:
template <class T, class Ta>
class Partialy<T, typename std::enable_if<std::is_base_of< BaseTpl<Ta>, T >::value>::type>
{
public:
void say()
{
std::cout << "Partialy special with TPL" << std::endl;
}
};
Пример 2 не скомпилируется
Компилятор выдает ошибку "template parameters not used in partial specialization:"
(Полный код: http://ideone.com/gZ6J2 )
Так что вопрос в том. Есть ли способ написать частичную специализацию, которая будет работать для всех классов, которые получены из BaseTpl
,
Список классов, по которым должна работать специализация:
class A1 : public BaseTpl<int>
class A2 : public BaseTpl<std::string>
class A3 : public BaseTpl<vector<int> >
...
Как у вас есть, невозможно, чтобы компилятор соответствовал Ta
против любого типа. Представьте, что у вас было это:
class DerivedTpl : public BaseTpl<int>, public BaseTpl<char>
{};
Какой тип будет Ta
быть, когда он пытается соответствовать?
Для вашей конкретной проблемы одним из решений является введение всеобъемлющего базового класса выше BaseTpl
:
class BaseNonTpl {};
template <class T>
class BaseTpl : BaseNonTpl
{};
Затем измените частичную специализацию, чтобы искать этот базовый класс.
template <class T>
class PartialyTpl<T, typename std::enable_if<std::is_base_of< BaseNonTpl, T >::value>::type>
Таким образом, компилятору не нужно пытаться выяснить, какой базовый класс вы хотели использовать.
Других решений пока нет …