I found GCC 7 has implemented guaranteed copy elision, and I tried the code below in wandbox:
#include <iostream>
struct NonMovable
{
NonMovable() noexcept = default;
NonMovable(NonMovable&&) noexcept = delete;
NonMovable& operator=(NonMovable&&) noexcept = delete;
};
NonMovable Make()
{
return {};
}
int main()
{
//[[maybe_unused]] const auto x = Make();
//const auto z = NonMovable{};
[[maybe_unused]] const auto y = NonMovable{NonMovable{}};
}
And I got compile error:
prog.cc: In function 'int main()':
prog.cc:20:60: error: use of deleted function 'NonMovable::NonMovable(NonMovable&&)'
[[maybe_unused]] const auto y = NonMovable{NonMovable{}};
^
prog.cc:6:5: note: declared here
NonMovable(NonMovable&&) noexcept = delete;
^~~~~~~~~~
According to cppreference:
In initialization, if the initializer expression is a prvalue and the cv-unqualified version of the source type is the same class as the class of the destination, the initializer expression is used to initialize the destination object:
T x = T(T(T())); // only one call to default constructor of T, to initialize x
So I think it should be equal to const Movable y{};
. What's wrong?
List-initialization gives you no precise control over what happens. Basically the committee has guessed what the programmer might want to do most probably and assigned the corresponding meanings.
If you want to have precise control, use non-list initialization. For that, your testcase should work definitely.
If you stick to list-initialization, then for aggregates, I think current draft wording will do it and applies guaranteed copy "elision", because they say
If T is an aggregate class and the initializer list has a single element of type cv U, where U is T or a class derived from T, the object is initialized from that element (by copy-initialization for copy-list-initialization, or by direct-initialization for direct-list-initialization).
In addition, you might get what you want in a future revision of the Standard or in a defect report resolution even for non-aggregates. I believe that your class is an aggregate, so it should compile. But perhaps there's something I'm missing here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With