JadziaMD
JadziaMD

Reputation: 2760

Duplicate Derived Object via C++ Template

I know this doesn't compile, and I understand that the "DerivedTemplate" type doesn't directly implement the abstract member function. What I would like to know is why, i.e. what rule prevents this from working?

#include <iostream>
#include <memory>

template<typename DuplicateType, typename DuplicatedReturnType = DuplicateType>
struct EnableDuplication
{
    virtual ~EnableDuplication()
    {}
    virtual std::unique_ptr<DuplicatedReturnType> duplicate() const
    {
        std::cout << "Using the templated duplication." << std::endl;
        const auto& thisObj{static_cast<const DuplicateType&>(*this)};
        return std::make_unique<DuplicateType>(thisObj);
    }
};

struct Base
{
    Base(int value) : value_(value)
    {}
    virtual ~Base()
    {}
    virtual std::unique_ptr<Base> duplicate() const =0;

    const int value_;
};

struct DerivedTemplate : Base, EnableDuplication<DerivedTemplate, Base>
{
    DerivedTemplate(int value) : Base(value)
    {}
};

struct DerivedImplement : Base
{
    DerivedImplement(int value) : Base(value)
    {}
    virtual std::unique_ptr<Base> duplicate() const override
    {
        std::cout << "Using the implented duplication." << std::endl;
        return std::make_unique<DerivedImplement>(*this);
    }

};

void printValue(const Base& original, const std::unique_ptr<Base>& copy)
{
    std::cout << "Value of derived is: " << original.value_ << 
        "\nValue of copy is: " << copy->value_ << std::endl;
}

int main(int argc, const char* argv[])
{
    DerivedTemplate dt{5};
    auto copyt{dt.duplicate()};
    printValue(dt, copyt);

    DerivedImplement di{5};
    auto copyi{di.duplicate()};
    printValue(di, copyi);
    return 0;
}

Upvotes: 1

Views: 102

Answers (2)

AndyG
AndyG

Reputation: 41220

It doesn't compile because DerivedTemplate derives from Base yet does not implement a pure virtual function:

virtual std::unique_ptr<Base> duplicate() const =0;

It will work if you implement said function:

struct DerivedTemplate : Base, EnableDuplication<DerivedTemplate, Base>
{
    DerivedTemplate(int value) : Base(value)
    {}

    virtual std::unique_ptr<Base> duplicate() const override
    {
        std::cout << "DerivedTemplate::duplicate()\n";
        return std::make_unique<DerivedTemplate>(*this);
    }
};

Demo

Upvotes: 0

Markus Zaczek
Markus Zaczek

Reputation: 154

Your hirarchy is like so:

EnableDuplication  Base
     \              /
     DerivedTemplate

DerivedTemplate inherits the same method from both base classes. You are not overriding anything. In my opinion your statement is wrong:"and I understand that the "DerivedTemplate" type doesn't directly implement the abstract member function." - The problem is it doesn't even indirectly. It just doesn't at all. What you want the language to do is to override but that you haven't told it to do so.

Upvotes: 1

Related Questions