c++ - 我看到的所有基于 std::move() 的 std::swap() 实现都是错误的吗?

标签 c++ c++11 swap move-semantics move-constructor

<分区>

Possible Duplicate:
What can I do with a moved-from object?

例如,参见 this code :

template<class T> 
void swap(T& a, T& b) 
{ 
    T tmp(std::move(a));
    a = std::move(b); 
    b = std::move(tmp);
} 

这只是我的问题,还是这里有错误?如果你moveatmp,那么a不就失效了吗?

即从 ba 的 move 赋值不应该是一个 move 构造函数调用,而不是放置 new 吗?
如果不是,那么 move 构造函数和 move 赋值运算符有什么区别?

template<class T>
void swap(T& a, T& b)
{
    T tmp(std::move(a));
    new(&a) T(std::move(b));
    new(&b) T(std::move(tmp));
}

最佳答案

当您将数据从对象中移出时,预期的语义是被移出的对象最终处于未指定但有效 状态。这意味着您无法预测对象将处于什么状态,除非它是一个格式正确的对象。这与“这个对象已经死了”不太一样。将数据移出对象并不会结束对象的生命周期 - 它只是将其状态更改为未指定的状态 - 因此为该对象分配新值是完全安全的。

因此,交换函数的初始版本是安全的。从 a move 数据后,该对象拥有一些未指定的“安全但不可预测”的值。然后在 move 分配 b 的值时覆盖该值。

第二个版本是不安全的,因为在您尝试在其上构造新对象之前 a 的生命周期尚未结束。这会导致未定义的行为。

希望这对您有所帮助!

关于c++ - 我看到的所有基于 std::move() 的 std::swap() 实现都是错误的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11691512/

相关文章:

javascript - 三星智能电视 - SEF 与 PNaCL

C++ 如何绑定(bind)和调用模板化类型方法

linux - 如果我的交换使用率为 100%,我应该担心吗?

Python:如何有效地创建数组的所有可能的 2 元素交换?

C++ 如何在 while 循环中正确使用线程

c++ - 路亚/C++ : __index is always invoked even the table's field is known

c++ - 编译 C++ 代码,然后反编译它?

C++ if/else语句问题

c++ - 关联容器引用

c++ - 特征张量模块 : how to swap cols or rows?