mercredi 1 juin 2016

How implementing move constructor affects return value optimization?

Consider the following code snippet:

#include <iostream>
#include <string>

class A { 
 public:
    A() { 
        std::cout << "A::A()\n";
    } 

    ~A() { 
        std::cout << "A::~A()\n";
    } 

    A(const A&) = delete;

    A(A&&) { 
        std::cout << "A::A(A&&)\n";
    };

};

A f() { 
    A a;
    return a;
}

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

It compiles fine with g++ and clang++ and output is

A::A()
A::~A()

It seems like RVO kicks in in that case. Note that no move constructor is being called.

However, if one will remove that non-used move constructor from the code above and snippet turns into this:

#include <iostream>
#include <string>

class A { 
 public:
    A() { 
        std::cout << "A::A()\n";
    } 

    ~A() { 
        std::cout << "A::~A()\n";
    } 

    A(const A&) = delete;

};

A f() { 
    A a;
    return a;
}

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

Both clang++ and g++ refuse to compile this because of copy-constructor of class A is marked as deleted, so it seems that no RVO takes place.

How removing non-used move constructor could lead to this?

Aucun commentaire:

Enregistrer un commentaire