Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is copy assignment called but not move assignment? [duplicate]

Tags:

c++

c++11

Here are my test class. VTX has both copy assignment and move assignment. VTZ has a constructor that takes VTS&& to initialize its vtx memeber.

    struct VTX
    {
    int x;
    vector<int> vts;

    VTX & operator= (const VTX & other)
    {
        x = other.x;
        vts = other.vts;
        cout << "copy assignment\n";
        return *this;
    }

    VTX & operator= (VTX && other)
    {
        x = other.x;
        vts = std::move(other.vts);
        cout << "move assignment\n";
        return *this;
    }

    };

    struct VTZ
    {
    VTX vtx;
    VTZ(VTX && vvv)
    {
        vtx = vvv;
    }

    VTZ()
    {}
    };

Test code:

    int main(VOID)
    {
        VTX vtx;
        vtx.vts.resize(10);
    
        VTZ vtz(std::move(vtx));
        return 0;
    }

I think the move assignment of VTX will be called when VTZ is constructed. But

Output:

copy assignment

I'm really confused why is copy assignment called but not move assignment?

like image 327
Paler Avatar asked Feb 18 '26 04:02

Paler


2 Answers

Because vvv is an lvalue expression (even its type is VTX &&). Types and value categories are different things.

The following expressions are lvalue expressions:

  • the name of a variable, a function, a template parameter object (since C++20), or a data member, regardless of type, such as std::cin or std::endl. Even if the variable's type is rvalue reference, the expression consisting of its name is an lvalue expression;

You can use std::move to convert it to rvalue (xvalue) expression,

VTZ(VTX && vvv)
{
    vtx = std::move(vvv);
}
like image 85
songyuanyao Avatar answered Feb 20 '26 17:02

songyuanyao


To put it another way (from the other answer currently here), this line right here:

vtx = vvv;

performs a copy, not a move.

If you want to move, you have to do something like this answer from another question:

VTZ(VTX && vvv) : vtx(std::move(vvv)) {

}

Or, you could do as songyuanyao suggested. Either one will work.


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!