为什么std :: move返回的对象不会立即销毁

Pon*_*279 7 c++ c++11

我测试了以下代码:

#include <iostream>
using namespace std;
class foo{
public:
    foo()       {cout<<"foo()"<<endl;}
    ~foo()      {cout<<"~foo()"<<endl;}
};

int main()
{
    foo f;
    move(f);
    cout<<"statement \"move(f);\" done."<<endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出是:

foo()
statement "move(f);" done.
~foo()
Run Code Online (Sandbox Code Playgroud)

但是,我预计:

foo()
~foo()
statement "move(f);" done.
Run Code Online (Sandbox Code Playgroud)

根据函数移动的源代码:

  template<typename _Tp>
    constexpr typename std::remove_reference<_Tp>::type&&
    move(_Tp&& __t) noexcept
    { return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }
Run Code Online (Sandbox Code Playgroud)

返回的对象是一个正确的值,那么为什么不立即销毁呢?



-------------------------------------------------- ---------------
我想我只是混淆了rvalue和rvalue引用.
我修改了我的代码:

#include <iostream>

template<typename _Tp>
constexpr typename /**/std::remove_reference<_Tp>::type /* no && */
/**/ mymove /**/ (_Tp&& __t) noexcept
{ return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }

using namespace std;
class foo{
public:
    foo()       {cout<<"foo() at "<<this<<endl;} /* use address to trace different objects */
    ~foo()      {cout<<"~foo() at "<<this<<endl;} /* use address to trace different objects */
};

int main()
{
    foo f;
    mymove(f);
    cout<<"statement \"mymove(f);\" done."<<endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

现在我得到了我一直期待的东西:

foo() at 0x22fefe
~foo() at 0x22feff
statement "mymove(f);" done.
~foo() at 0x22fefe
Run Code Online (Sandbox Code Playgroud)

Ste*_*sop 14

从对象移动不会改变其生命周期,只会改变其当前值.您的对象foo在返回时被销毁main,这是在您的输出之后.

此外,std::move不会离开对象.它只返回一个rvalue引用,其引用是对象,可以从对象移动.


Pet*_*ker 5

当对象超出范围时会被破坏.从物体移动不会改变这一点; 根据移动构造函数或移动赋值操作符的作用,移动后对象的状态可能不同,但尚未被销毁,因此实际的规则是从对象移动必须使其保持在可以被摧毁.

除此之外,正如@ R.MartinhoFernandes指出的那样,std::move没有做任何事情.它是对象的移动构造函数或移动赋值运算符,它执行任何需要完成的操作,并且不会在调用中应用std::move; 当移动的对象用于构造新对象(移动构造函数)或分配给现有对象(移动赋值运算符)时应用它.像这样:

foo f;
foo f1(f);            // applies foo's copy constructor
foo f2(std::move(f)); // applies foo's move constructor
foo f3, f4;
f3 = f;               // applies foo's copy assignment operator
f4 = std::move(f1);   // applies foo's move assignment operator
Run Code Online (Sandbox Code Playgroud)