0
#include <iostream>

class A {
public:
    A() { std::cout << "Constructor" << std::endl; }
    A(const A& a) { std::cout << "Copy Constructor" << std::endl; }
    A& operator=(const A& a) { std::cout << "Copy = operator" << std::endl; }
    A(A&& a) { std::cout << "Move Constructor" << std::endl; }
    A& operator=(A&& a) { std::cout << "Move = operator" << std::endl; }
    ~A() { std::cout << "Destructor" << std::endl; }
};

void f(A&& a) { std::cout << "function" << std::endl; }

int main() {
    f(A());
    return 0;
}

The output of the following program is:

Constructor
function
Destructor

Why is the move-constructor not called here? It seems like copy elision occurs even if I compile with the flag -fno-elide-constructors: g++ test.cpp -fno-elide-constructors -std=c++11

cuv
  • 1,159
  • 2
  • 10
  • 20
  • 6
    Am I being spectacularly dumb? Surely `A()` invokes the default constructor, then the anonymous temporary can bind to `f(A&&)`. What am I missing? A move constructor can only be called when you have a constructed object. – Bathsheba Nov 25 '16 at 08:48
  • 1
    @Bathsheba: I don't think you are missing anything. Given `A foo();`, then `A a{foo()};` would invoke the move constructor, but as it is, there is nothing to move to. – Martin Bonner supports Monica Nov 25 '16 at 08:54
  • @Bathsheba "What am I missing?" I don't know... Some good quality personal time? Perhaps some sleep too? (don't mind me, just clowning around. Friendly kidding, no malice in it). – Adrian Colomitchi Nov 25 '16 at 08:54
  • This isn't the issue, but don't use `std::endl` unless you need the extra stuff that it does; `'\n'` ends a line. – Pete Becker Nov 25 '16 at 14:22

1 Answers1

6

Short answer: You are not move-constructing anything.

You are just creating a temporary Aobject and then passing a reference to it. If you want to see move construction, you could e.g. change the signature of f to

void f(A a)
MikeMB
  • 20,029
  • 9
  • 57
  • 102