dimanche 18 novembre 2018

How to implicitly convert returned value to base class without invoking copy constructor?

Consider two classes such as these:

class Base {
public:
    Base() { puts("Create base"); }
    Base(const Base &) { puts("Copy base"); }
    Base(Base &&) { puts("Move base"); }
    virtual ~Base() { puts("Delete base"); }
    Base & operator=(const Base &) = delete;
};

class Derived : public Base {
public:
    Derived() { puts("Create derived"); }
    Derived(const Derived &) { puts("Copy derived"); }
    Derived(const Base &) { puts("Copy derived from base"); }
    Derived(Derived &&) { puts("Move derived"); }
    Derived(Base &&) { puts("Move derived from base"); }
    virtual ~Derived() { puts("Delete derived"); }
    Derived & operator=(const Derived &) = delete;
};

and a function:

Base fn() {
    Derived d;
    // Fill in d here
    return d;
}

Copying the base class is a very expensive operation, however because the derived class is not much different, it could be converted into a base object using move semantics. However, I can't get the compiler to use that implicitly instead of the copy construction. I tried adding the following with no success:

Base::Base(Derived &&);
Derived::operator Base &&() &&;
Derived::operator Base() &&;

Is there a way to avoid the copy constructor by only changing the two classes and not the function fn?

EDIT: I know how to do it if I could change the function fn but I can't.

Aucun commentaire:

Enregistrer un commentaire