'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
Solution 1:[1]
This is C++ Standard Core Language issue 2403, which is currently in open status.
The example given there is almost identical to yours:
struct Noncopyable {
Noncopyable();
Noncopyable(const Noncopyable &) = delete;
};
Noncopyable make(int kind = 0);
struct AsBase : Noncopyable {
AsBase() : Noncopyable(make()) {} // #1
};
struct AsMember {
Noncopyable nc;
AsMember() : nc(make()) { } // #2?
};
And the comment says
All implementations treat #1 as an error, invoking the deleted copy constructor, while #2 is accepted. It's not clear from the current wording why they should be treated differently.
Actually all implementations treat #1 as an error is not quite true, since Visual Studio compiler performs copy elision here and accepts both this example and yours. Demo: https://gcc.godbolt.org/z/G61fKT55K
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Fedor |
