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 )
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 )
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 Ta
against any type. Imagine you had this:
class DerivedTpl : public BaseTpl<int>, public BaseTpl<char>
{};
What type will Ta
be when it tries to match?
For your particular problem, one solution is to introduce an all-encompassing base class above BaseTpl
:
class BaseNonTpl {};
template <class T>
class BaseTpl : BaseNonTpl
{};
Then, modify the partial specialisation to look for that base class instead.
template <class T>
class PartialyTpl<T, typename std::enable_if<std::is_base_of< BaseNonTpl, T >::value>::type>
That way, the compiler doesn't have to try and figure out what base class you meant to use.