elcuco
elcuco

Reputation: 9208

Template interface return types

I am trying to make a template, which should be used as an interface to implement. This kind of thing is easy on Java, but I am fighting C++. The code does not compile in the C2::action() method. It seems the compiler thinks I am trying to allocate an abstract type.

Am I missing a copy constructor... or... what?

template <class T> 
class C1 {
public:
    virtual C1<T> action() = 0;
};

template <class T>
class C2: public C1<T> {
public:
    virtual C1<T> action(){
        C2<T> sub;
        return sub;
    }

};

C2<int> t;
t.action();

Upvotes: 1

Views: 375

Answers (1)

Fran&#231;ois Andrieux
Fran&#231;ois Andrieux

Reputation: 29032

C1<T> action() returns an object of type C1<T>. Since C1<T> is abstract, you can never succeed in returning from action. Even if you try to initialize this return value with concrete type like C2<T> it will experience object slicing and "turn into" a C1<T> (or try to). This tries to construct a C1<T> based on your C2<T>. But since C1<T> is abstract it can't be constructed.

To enable polymorphism you need to rely on references or pointers. While a C1<T> is always a C1<T>, a C1<T>* can point to an object of type C1<T> or any other type that inherits publically form it such as C2<T>. You could try returning a std::unique_ptr<C1<T>> instead of C1<T> :

#include <memory>

template <class T> 
class C1 {
public:
    virtual std::unique_ptr<C1<T>> action() = 0;
};

template <class T>
class C2: public C1<T> {
public:
    virtual std::unique_ptr<C1<T>> action() override {
        return std::make_unique<C2<T>>();
    }

};

Upvotes: 2

Related Questions