Using member function templates with inheritance

How do member function templates interact with inheritance? Can I override a member function template in a derived class?

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.

Member Function Templates

Learn how to create and use member function templates in classes and structs, including syntax, instantiation, and advanced techniques

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

When should I use member function templates vs regular member functions?
How do I decide when it makes sense to use a member function template instead of a regular member function?
Passing member function templates as arguments
Can I pass a member function template as an argument to another function? How would I do that?
Template specialization for member function templates
Is it possible to specialize a member function template? How would I do that?
Member function templates and static members
Can I declare a static member variable inside a member function template? How would I define it?
Using SFINAE with member function templates
Can I use SFINAE (Substitution Failure Is Not An Error) with member function templates? How does that work?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant