为何此协程示例中的std::move从严格意义上讲是冗余的?
CoroTask移动语义中
std::move冗余性的解析 先看Josuttis《C++20》§14.2.7中给出的CoroTask移动语义实现代码:
class CoroTask { … public: struct promise_type; using CoroHdl = std::coroutine_handle<promise_type>; private: CoroHdl hdl; public: … // support move semantics: CoroTask(CoroTask&& c) noexcept : hdl{std::move(c.hdl)} { c.hdl = nullptr; } CoroTask& operator=(CoroTask&& c) noexcept { if (this != &c) { // if no self-assignment if (hdl) { hdl.destroy(); // - destroy old handle (if there is one) } hdl = std::move(c.hdl); // - move handle c.hdl = nullptr; // - moved-from object has no handle anymore } return *this; };
为什么std::move(c.hdl)是冗余的?
std::coroutine_handle的本质特性:std::coroutine_handle是轻量级句柄,内部仅持有指向协程状态的指针。它的移动构造/赋值与拷贝构造/赋值行为完全一致——都是简单复制指针值,不存在真正意义上的资源转移(协程状态的所有权由谁调用destroy()决定,而非句柄的拷贝/移动操作)。左值与右值的无差别处理:尽管参数
c是右值引用,但c.hdl本身是左值。直接写hdl = c.hdl和hdl = std::move(c.hdl)的执行效果完全相同,因为std::coroutine_handle的赋值运算符对左值、右值的处理逻辑没有差异,都是复制指针。后续操作的覆盖:在移动构造和赋值逻辑中,紧接着会将
c.hdl置为nullptr,彻底切断原句柄与协程状态的关联。无论是否使用std::move,最终新句柄都会持有原指针,原句柄都会被清空,语义和结果完全一致。
综上,此处的std::move没有带来任何实际的语义或性能收益,因此是冗余的。
内容的提问来源于stack exchange,提问作者Enlico
相关产品推荐
相关产品推荐

