Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rvalue references without std::move [duplicate]

I have following class

class widget {
// The methods only print their name, i.e. c'tor, destructor etc.
public:
    widget();
    widget(const widget&);
    widget(widget&&);
    ~widget();
    auto operator=(const widget&)  -> widget&;
    auto operator=(widget&&) -> widget&;
};

which I use in following code

#include "widget.h"

auto main() -> int {

    widget c(std::move(widget()));
    c = std::move(widget());

    return 0;
};

The resulting behavior is comprehensible to me. In the first call a widget is constructed, then the move constructor is invoked and the destructor is called on the temporary widget.

The second call does the same, expect for calling the move assignment operator instead of the move constructor. Leaving the main method, the destructor is invoked on c.


Now comes the interesting part:

#include "widget.h"

auto main() -> int {

    widget c((widget()));
    c = widget();

    return 0;
};

If I leave out the call to std::move, the first case stops working and results in just one constructor call. Whereas the second case is still working as before.

What am I missing here? Why are those two function calls treating their parameters differently? I tried this on gcc and clang.

like image 527
mike Avatar asked May 05 '15 16:05

mike


1 Answers

widget() is a pure rvalue (prvalue), so in the line

widget c((widget())); // use widget c{widget()} or c{widget{}} for more clear code

it will be moved. However, the compiler just performs copy/move elision. Compile with -fno-elide-constructors and you'll see the calls to the move constructors in all their glory.

Whenever you explicitly use std::move to move a prvalue, you're not allowing the compiler to perform the elision; that's why you see the move constructor in action in the first snippet. That's why it's almost always a bad idea to try to "help" the compiler by using a std::move as the return (unless you really want to return a rvalue reference).

like image 52
vsoftco Avatar answered Sep 28 '22 04:09

vsoftco