C++ template function, inheritance, shared_ptr

68 Views Asked by At

I guess this is a very basic question but I'm still asking because I suspect the compiler acts as expected and the error rather comes from me!

I'd like to implement an abstract class with a template abstract function. As you may know, that's not possible: a template function cannot be abstract.

So I have to implement a dummy function in my base class. Inconvenient for many reasons, but so be it.

The problem is that, as soon as I'm using pointers, the compiler calls the base class function, not the child class implementation.

How to solve this ?


#include <iostream>
#include <memory>

class Person
{
  protected:
    std::string _first_name;
    std::string _last_name;

  public:
    Person(std::string first_name, std::string last_name):
        _first_name(first_name), _last_name(last_name){}

    const std::string & first_name() const { return _first_name; }
    const std::string & last_name() const { return _last_name; }
};

// ==============================================================================
// Using template functions.

class HumanPrinterBase
{
  public:
    template <typename T>
    void print(const T & person) const { std::cout << "HumanPrinterBase::print()" << std::endl; }
};

class HumanFirstNamePrinter : public HumanPrinterBase
{
  public:
    template <typename T>
    void print(const T & person) const
    {
        std::cout << person.first_name() << std::endl;
    }
};


// ==============================================================================
// Using non-template functions.

class PersonPrinterBase
{
  public:
    virtual ~PersonPrinterBase() = default;
    virtual void print(const Person & person) const = 0;
};

class PersonFirstNamePrinter : public PersonPrinterBase
{
  public:
    virtual void print(const Person & person) const override
    {
        std::cout << person.first_name() << std::endl;
    }
};


int main(int argc, char const *argv[])
{
    Person person("John", "Doe");

    std::unique_ptr<HumanPrinterBase> hp = std::make_unique<HumanFirstNamePrinter>();
    hp->print(person); // "HumanPrinterBase::print()" (fails)

    std::unique_ptr<PersonPrinterBase> pp = std::make_unique<PersonFirstNamePrinter>();
    pp->print(person); // "John" (works)

    return 0;
}

0

There are 0 best solutions below