0

The below code example is just focused on constructors. Basically, my question concerns why the move constructor is not called, and if its because it is somehow "optimized away" by the compiler?

#include <iostream>

class Foo{
public:
    int x_;
    Foo(const int x = 0) : x_{x} {std::cout << "Default constructor used..." << std::endl;}
    Foo(Foo&& f) : x_{f.x_} {std::cout << "Move constructor used..." << std::endl;}
    Foo(const Foo& f) : x_{f.x_} {std::cout << "Copy constructor used..." << std::endl;}
};

Foo operator+(const Foo& f1, const Foo& f2)
{
    Foo f; // default constructor used
    f.x_ = f1.x_ + f2.x_;
    return f;
}

int main()
{
    Foo f1(3), f2(2); // two default constructor calls
    Foo f = f1; // copy constructor gets called
    Foo f_ = f1 + f2; // move is NOT called
    std::cout << f.x_ << std::endl;

    return 0;
}

Based on what I've read on move constructors the move constructor should have been called for the line

Foo f_ = f1 + f2;

but it is not.

f1 + f2

is not an lvalue, but an rvalue.

In fact, it appears like NO constructor is called for the construction of f_. The output of this program is:

Default constructor used...
Default constructor used...
Copy constructor used...
Default constructor used...
3

To me it looks like the construction of f_ is "hidden". I use g++ version 4.8.1 (64-bit) on Windows 8.1.

Appreciate any help. Thank you.

jensa
  • 2,792
  • 2
  • 21
  • 36
  • 1
    [Copy elision](http://en.cppreference.com/w/cpp/language/copy_elision) (which also applies to moves). Specifically, NRVO. It is allowed but not required by the standard, and in this case your compiler was able to make it work. –  Nov 22 '14 at 10:54
  • Thanks. So what's happening is in fact the compiler at work. – jensa Nov 22 '14 at 10:59

0 Answers0