How do RVO and rvalue return by function?

To understand how the compiler chooses the class constructor, I wrote the following code:

#include <iostream>

struct Widget
{
    Widget(Widget&& w){std::cout << "Move ctor" << std::endl;}
    Widget(void){std::cout << "Default ctor" << std::endl;}
    Widget(const Widget& w){std::cout << "Copy ctor" << std::endl;}
};

Widget make_widget(void) //helper function
{
    Widget w;
    return w;
}

int main(void)
{
    Widget w(make_widget());
}

In accordance with clause 25 of Effective Modern C ++, the compiler treats w as a reference to rvalue due to optimization of the return value. So I was expecting a Widget w(make_widget())move constructor to be called. but this is not so. In addition, it prints only

Default

So I have no idea which version of the constructor was called. Then I also tried to explicitly return the rvalue value. That is return std::move(w) , Against my expectation, given the above result, he correctly named the move constructor and printed

Default
Move

I seem to be in the maze of rvalue. Please tell me what is going on there.

+4
1

25 " ++" w rvalue - .

, , . RVO , rvalue . w make_widget main l Widget. Widget&&, lvalue ( ), - rvalue reference.

Default, , - Widget w; make_widget(). - w main, . RVO, -fno-elide-constructors g++, ( RVO V++ ),

Default (first creation)
Move    (creation of temporary with the move ctor)
Move    (copying of temporary to the one in main)

return w return std::move(w), rvalue, .

+3

All Articles