Частичная специализация с нетабличным классом, который унаследован от шаблонного класса

Пример 1

Если у нас есть 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 )

Пример 2

Если бы я только сделал 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> >
...

1

Решение

Как у вас есть, невозможно, чтобы компилятор соответствовал 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>

Таким образом, компилятору не нужно пытаться выяснить, какой базовый класс вы хотели использовать.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]