Hidden motion design

Why sometimes the call to move-constructor fails? Testing move-semantics (live code) :

struct Test {
    int id;
    Test(int id) : id(id) {
        cout << id << "  Test() " << endl;
    }
    ~Test() {
        cout << id << "  ~Test() " << endl;
    }
    Test(const Test &t) : id(t.id) {
        cout << id << "  Test(const Test &t) " << endl;
    }
    Test(Test &&t) : id(t.id) {
        cout << id << "  Test(Test &&t) " << endl;
    }
    Test &operator=(const Test &t) {
        cout << id << "  operator=(const Test &t) " << endl;
        return *this;
    }
    Test &operator=(Test &&t) {
        cout << id << "  operator=(Test &&t) " << endl;
        return *this;
    }
};

void f(Test z) {
    cout << z.id << "  f(Test z) " << endl;
}

int main() {
    f(Test(1));

    Test t(2); f(t);
}

Output:

1  Test() 
1  f(Test t)               <---// where is move constructor ?!
1  ~Test() 
2  Test() 
2  Test(const Test &t)     <---// copy constructor of t(2)
2  f(Test t) 
2  ~Test() 
2  ~Test()

The test shows that the constructor instance is being called.

But after the f(Test(1));function fis called without calling move-constructor for the rvalue object Test(1).

Is this an implicit compiler optimization? or did I miss an important point?

+4
source share
2 answers

The compiler is explicitly allowed to copy (or move) temporary objects. In principle, the object is being built in the place where an effective result is expected. This permission is even allowed if the constructor or destructor has side effects.

- 12.8 [class.copy], 31:

/ , , / / , . / , , . /, , ( ):...

, ,

  • return .
  • throw .
  • .
  • .

, , 31.8 [class.copy].

/ - , , ,

f(std::move(Test(1)));

.

+8

. (copy elision) gcc :

-fno-elide-constructors
0

All Articles