samedi 6 juin 2020

C++: rvalue reference constructor and copy-elision

I'm trying to understand the rvalue reference constructor and assignment operator. I created the following source code which should invoke the rvalue reference constructor, however it doesn't occur. My suspicion is copy-elision optimization is the cause. Does anyone know if that's the reason? Also, if copy-elision is the cause, what is the point of of rvalue references in the code? Appreciate your guidance!

#include <iostream>
#include <vector>
using namespace std;

class X {
public:
    X() : v{new vector<int>(0)} { }
    X(const X&);
    X(X&&);
    X& operator=(const X& rhs);
    X& operator=(X&& rhs);
private:
   vector<int> *v;
};

X::X(const X& a)
{
    cout << "copy constructor" << endl;
    for (auto p : *(a.v))
        v->push_back(p);
}

X::X(X&& a) : v{a.v}
{
    cout << "rval ref constructor" << endl;
    a.v = nullptr;
}

X& X::operator=(const X& rhs)
{
    cout << "assignment operator" << endl;
    delete v;
    v = new vector<int>();
    for (auto p : *(rhs.v))
        v->push_back(p);
    return *this;
}

X& X::operator=(X&& rhs)
{
    cout << "rval ref assignment op" << endl;
    swap(v, rhs.v);
    return *this;
}

X f0()
{
    return X(); // copy-elision no move called
    // return move(X());
}

int main(int argc, char *argv[])
{
    X x1(f0());

    return 0;
}

SOLUTION: Add the following to main():

X x2(std::move(x1));

this manually indicates the object x1 can be moved from to work around copy-elision. copy-elision is not always invoked, so there may be cases where the rvalue reference constructor and assignment operator are required.

Aucun commentaire:

Enregistrer un commentaire