Member function templates and inheritance interact in interesting ways. You can define member function templates in a base class and still override them in derived classes, but there are a few things to keep in mind.
First, when you define a member function template in a base class, it doesn't create a single function that can be overridden. Instead, it creates a template for functions that can be instantiated.
Here's an example:
#include <iostream>
class Base {
public:
template <typename T>
void func(T x) {
std::cout << "Base: " << x << std::endl;
}
};
class Derived : public Base {
public:
template <typename T>
void func(T x) {
std::cout << "Derived: " << x << std::endl;
}
};
int main() {
Derived d;
d.func(42); // calls Derived::func
d.func(3.14); // also calls Derived::func
}
Derived: 42
Derived: 3.14
In this code, both Base
and Derived
have a member function template func
. When we call d.func
, it always calls Derived::func
, regardless of the argument type. That's because Derived::func
is not actually overriding Base::func
, it's hiding it.
If you want to truly override a specific instantiation of a base class member function template, you need to provide an explicit specialization in both the base and the derived class:
#include <iostream>
class Base {
public:
template <typename T>
void func(T x) {
std::cout << "Base: " << x << std::endl;
}
};
template <>
void Base::func<int>(int x) {
std::cout << "Base specialization for int: "
<< x << std::endl;
}
class Derived : public Base {
public:
template <typename T>
void func(T x) {
std::cout << "Derived: " << x << std::endl;
}
// Override the base class's specialization
// for int
void func(int x) {
std::cout << "Derived specialization for"
" int: " << x << std::endl;
}
};
int main() {
Derived d;
d.func(42); // calls Derived::func
d.func(3.14); // also calls Derived::func
}
Derived specialization for int: 42
Derived: 3.14
Now, when you call d.func(42)
, it will call the specialization in Derived
, but d.func(3.14)
will still call the generic func
from Base
.
Inheritance with member function templates can be complex, so it's important to consider your design carefully. In many cases, it might be simpler to use regular virtual functions for runtime polymorphism and reserve member function templates for static polymorphism within a single class.
Answers to questions are automatically generated and may not have been reviewed.
Learn how to create and use member function templates in classes and structs, including syntax, instantiation, and advanced techniques