Example 1
If we have Base and Derived classes
class Base
{};
class Derived : public Base
{};
and a template class
template <class T, class Enabler=void>
class Partialy
{
public:
void say()
{
std::cout << "Partialy Default" << std::endl;
}
};
We can write a partial specialization next way:
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;
}
};
Example 1 will work OK. (Full code: http://ideone.com/4FyrD )
Example 2
If only I make Base class template one:
template <class T>
class BaseTpl
{};
class DerivedTpl : public BaseTpl<int>
{};
The next partial specializetion don’t work:
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;
}
};
Example 2 won’t compile
The compiler throws an error "template parameters not used in partial specialization:" (Full code: http://ideone.com/gZ6J2 )
Question
So the question is. Is there any way to write partial specializaion which would work for all classes which are derived from BaseTpl.
The list of classes for which the specialization shold work:
class A1 : public BaseTpl<int>
class A2 : public BaseTpl<std::string>
class A3 : public BaseTpl<vector<int> >
...
The way you have it, it is impossible for the compiler to match the
Taagainst any type. Imagine you had this:What type will
Tabe when it tries to match?For your particular problem, one solution is to introduce an all-encompassing base class above
BaseTpl:Then, modify the partial specialisation to look for that base class instead.
That way, the compiler doesn’t have to try and figure out what base class you meant to use.