Override template member in Interface

Template methods cannot be virtual. One solution is to use static polymorphism to simulate the behavior of "template virtual" methods:

#include <iostream>
#include <stdexcept>
#include <string>

template<typename D>
class Base
{
    template<typename T>
    std::string _method() { return "Base"; }
public:

    template<typename T>
    std::string method()
    {
       return static_cast<D&>(*this).template _method<T>();
    }
};

class Derived : public Base<Derived>
{
    friend class Base<Derived>;

    template<typename T>
    std::string _method() { return "Derived"; }
public:
    //...
};

int main()
{
    Base<Derived> *b = new Derived();
    std::cout << b->method<bool>() << std::endl;
    return 0;
}

where method is the interface and _method is the implementation. To simulate a pure virtual method, _method would absent from Base.

Unfortunately, this way Base changes to Base<Derived> so you can no longer e.g. have a container of Base*.

Also note that for a const method, static_cast<D&> changes to static_cast<const D&>. Similarly, for an rvalue-reference (&&) method, it changes to static_cast<D&&>.


Another possible aproach to make your example work as you expect is to use std::function:

class Base {
  public:
    Base() {
      virtualFunction = [] () -> string { return {"Base"}; };
    }
    template <class T> string do_smth() { return virtualFunction(); }
    function<string()> virtualFunction;
};
class Derived : public Base {
  public:
    Derived() {
      virtualFunction = [] () -> string { return {"Derived"}; };
    }
};

int main() {
  auto ptr = unique_ptr<Base>(new Derived);
  cout << ptr->do_smth<bool>() << endl;
}

This outputs "Derived". I'm not sure that this is what you realy want, but I hope it will help you..


1) Your functions, in order to be polymorphic, should be marked with virtual

2) Templated functions are instantiated at the POI and can't be virtual (what is the signature??How many vtable entries do you reserve?). Templated functions are a compile-time mechanism, virtual functions a runtime one.

Some possible solutions involve:

  • Change design (recommended)
  • Follow another approach e.g. multimethod by Andrei Alexandrescu (http://www.icodeguru.com/CPP/ModernCppDesign/0201704315_ch11.html)

Tags:

C++

Templates