1

My code run in vs2019,release,x86. Here the constructor of c should be a right-valued reference, why not execute the move constructor but copy constructor?

#include<iostream>
class Test
{
public:
    int num{ 0 };
    Test(int num1) : num(num1) {}
    Test(const Test& rhs)
    {
        std::cout << "copy\n";
        num = rhs.num;
    }
    Test(Test&& rhs)
    {
        std::cout << "move\n";
        num = std::move(rhs.num);
    }
};

int main()
{
    Test a(10);
    Test&& b = std::move(a);
    Test c(b);    // copy
    Test d(std::move(a));  // move
    Test e(static_cast<Test&&>(a));   // move
}

copy move move

Xia Qizhen
  • 71
  • 6
  • Everything that has a name is a lvalue-reference. So when you access `Test&& b` in your code, you get a non-const lvalue-reference to `Test&&`, which by the reference collapsing rules becomes a `Test&`, and that binds to the copy contructor. – davidhigh Apr 08 '23 at 09:07
  • As an aside, moving *everything* doesn't magically make the code any faster. Like moving an `int` is still a copy, as `int` doesn't have a move constructor. Likewise, moving an object that just contains an `int` will not speed up the code either. Oh, and moving the same object more than once is no good. – BoP Apr 08 '23 at 09:12
  • `Test&& b = std::move(a);` Nothing is constructed so no constructor is called. b just refers to a. The ` std::move(a)` just says treat a as an rvalue but has no effect on its identity so it binds to an rvalue ref. – doug Apr 08 '23 at 20:02

0 Answers0