Search code examples
c++c++17return-value-optimization

Why isn't RVO applied to base class subobject initialization?


Why is the move constructor for Base mandatory in case of inheritance (class B) in the following code (both in gcc 7.2 and clang 4.0)? I would expect it not to be required with guaranteed copy elision in C++17, as in case of composition (class A).

struct Base {
    Base(Base&&) = delete;
    Base& operator=(Base&&) = delete;

    Base()
    {
    }
};

Base make_base()
{
    return Base{};
}

struct A {
    A() : b(make_base()) {} // <<<--- compiles fine

    Base b;
};

#ifdef FAIL
struct B : public Base {
    B() : Base(make_base()) {} // <<<--- "Base(Base&&) is deleted"
};
#endif

example


Solution

  • According to Richard Smith:

    This is a defect in the standard wording. Copy elision cannot be guaranteed when initializing a base class subobject, because base classes can have different layout than the corresponding complete object type.