The following code compiles fine, but produces a linker error:
class Base {};
class Derived : public Base {};
template
void f(const T&am
The linker error occurs because you haven't defined, only declared, the function template
template
void f(const T& value);
To avoid it, define the above template and your code will compile, but presumably it still doesn't do what you want.
When calling f
with an argument of type Derived
the above template is a better match compared to your specialization because the latter requires a derived-to-base conversion while the former doesn't.
You can achieve the behavior you want by using enable_if to allow the first template to participate in overload resolution only if the deduced template argument type is not Base
or a type derived from Base
.
template
typename std::enable_if::value>::type
f(const T& value) {
}
And change the other f
so it's not a specialization, but just an overload.
void f(const Base& value) {
// ...
}
Live demo
In general, prefer overloading function templates over specialization. Read this to learn about the pitfalls of function template specialization.