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


Можно ли написать частичную специализацию шаблона, которая используется только для типов классов, которые, например, наследуются от определенного класса или соответствуют некоторому другому ограничению, которое может быть выражено через признаки типа? то есть, что-то вроде этого:

class A{}

class B : public A{}

template<typename T>
class X{
    int foo(){ return 4; }
};

//Insert some magic that allows this partial specialization
//only for classes which are a subtype of A
template<typename T> 
class X<T>{
    int foo(){ return 5; }
};

int main(){
    X<int> x;
    x.foo(); //Returns 4
    X<A> y;
    y.foo(); //Returns 5
    X<B> z;
    z.foo(); //Returns 5
    X<A*> x2; 
    x2.foo(); //Returns 4
}
1 3

1 ответ:

Обычно, если требуется условная частичная специализация шаблона, необходимо указать дополнительный параметр, а затем использовать enable_if:

template<typename T, typename=void>
class X {
public:
    int foo(){ return 4; }
};

template<typename T>
class X<T, typename std::enable_if<std::is_base_of<A, T>::value>::type> {
public:
    int foo(){ return 5; }
};