How to move temporary object without std::move

Viewed 1405

Move constructor of class accepts rvalue reference which can be reference to temporary object. So, i have temporary object and appropriate move constructor which can accept reference to temporary object, but move constructor does not called. What`s wrong?

    //g++  5.4.0

#include <iostream>

class foo
{
    int data;
public:
    foo(int v) : data(v) {std::cout << "foo(int)\n";}

    foo(foo&& f)
    {
        std::cout << "moved\n";
    }

    void print()
    {
        std::cout << data;
    }
};

void acceptTmp(foo f)
{
    f.print();
}

int main()
{
    foo f1 = foo(100);
    f1.print();
    acceptTmp(foo(200)); //also does not move
}
2 Answers

What`s wrong?

Nothing is wrong, except for your expectation that the move constructor would be called.

Prior to C++17, the temporary object would indeed be moved into the argument from the point of view of the abstract machine. However, the standard allows the move to be elided by the compiler, by constructing the temporary directly in place of the object where it would be moved into. You cannot rely on the side-effects of the move constructor to occur.

Post C++17, there is no temporary object or move involved. The standard guarantees that the argument is constructed in place.


The lack of a move is a good thing. Moving an object is potentially slower than not moving it.

Usually the compiler perform the optimizations and the transformations to the code by applying the as-if rule. The copy/move elision is the only exception to the "as-if" rule. Compiler optimizes the copy and move operations even when there are side effects because the copy and move operations comes at a cost.

Of course before C++17, it depends on the compiler and maybe optimization level. But from c++17 onwards, the eliding is guaranteed.

If you want to instruct the compiler to not perform the elision, you can use -fno-elide-constructors compiler flag.

Please see the below links to understand more about the copy/move ellison:

What are copy ellision?

Related