Reputation: 119
I have the situation that I have an existing template class which works fine for all kind of datatypes. But now I need to specialize it for classes which derive from a specific class. But not the whole class should be specialized but only some functions.
I tried to do it like it is described in this post.
class BaseClass
{
public:
bool DoSomething()
{
return true;
}
};
class SubClass : BaseClass
{
};
template<typename T, typename _Alloc = std::allocator<T>>
class TemplateClass
{
public:
template<typename U = T, typename std::enable_if<
!std::is_base_of<BaseClass, U>::value>::type>
void print_line()
{
std::cout << "Parameter of general Type T" << std::endl;
}
template<typename U = T, typename std::enable_if<
std::is_base_of<BaseClass, U>::value>::type>
void print_line()
{
std::cout << "Parameter of specific Type BaseClass" << std::endl;
}
};
I try to use the template like this:
TemplateClass<BaseClass>* tc1 = new TemplateClass<BaseClass>();
tc1->print_line();
TemplateClass<SubClass>* tc2 = new TemplateClass<SubClass>();
tc2->print_line();
TemplateClass<int>* tc3 = new TemplateClass<int>();
tc3->print_line();
For each function call i get the error there was no fitting method found. Another point is that in this article they say that enable_if shouldn't be used to select between implementations.
Does anyone has an idea what my mistake is or how to do this correctly? Thanks in advance!
Upvotes: 1
Views: 258
Reputation: 2241
You can either change it to
template<typename U = T, typename std::enable_if<
!std::is_base_of<BaseClass, U>::value>::type* = nullptr>
void print_line()
{
std::cout << "Parameter of general Type T" << std::endl;
}
or
template<typename U = T>
typename std::enable_if<!std::is_base_of<BaseClass, U>::value, void>::type print_line()
{
std::cout << "Parameter of general Type T" << std::endl;
}
and the other one accordingly.
The idea behind both is to produce an error for one of the methods during the instantiation of the function templates. Due to the error, the corresponding method is not considered during overload resolution such that there is only one method (the one that did not produce the error) available, which will then be called.
std::enable_if
is used to produce this error, because if its first parameter is false
it does not define a type
member so the function template cannot be instantiated and will be removed from overloading resolution.
Search for SFINAE for more detailed information.
Upvotes: 1