由于我们已经移动了语义,所以特别推荐使用std :: swap吗?

fre*_*low 35 c++ templates swap move-semantics c++11

可能重复:
移动语义==自定义交换功能已过时?

这就是std::swapC++ 11中的样子:

template<typename T>
void swap(T& x, T& y)
{
  T z = std::move(x);
    x = std::move(y);
    y = std::move(z);
}
Run Code Online (Sandbox Code Playgroud)

如果我的类定义了移动构造函数和移动赋值运算符,我还是必须专注std::swap于我自己的类型,或者它会std::swap尽可能高效吗?

How*_*ant 31

专业化std::swap现在是可选的,但不是已弃用.理由是表现.

对于原型设计代码,甚至可能是大量的运输代码,std::swap都会很快.但是,如果您需要从代码中获取每一点内容,那么编写自定义交换仍然是一个重要的性能优势.

考虑一下你的类基本上有一个拥有指针的情况,你的移动构造函数和移动赋值只需要处理那个指针.计算每个成员的机器负载和存储:

移动构造函数:1个加载和2个存储.

移动分配:2个装载和2个存储.

自定义交换:2个加载和2个商店.

std::swap 是1个移动施工和2个移动任务,或:5个负载和6个商店.

自定义交换可能仍然比两倍或三倍快std::swap.虽然任何时候你都试图通过计算负荷和商店来计算某些东西的速度,但两者都会很快变得邪恶.

注意:在计算移动分配的成本时,请确保并考虑到您将进入移动值(在std::swap算法中).这通常会导致解除分配的成本,但是以分支为代价.

  • 我不是编译工程师.我猜这是可能的,但我不确定.我会犹豫要不要依赖它.在一天结束时,您将不得不以两种方式对其进行编码并进行测试.如果你的测试表明`std :: swap`同样快,那么结果可能与编译器/平台有关.如果你的应用程序没有在性能关键区域中"交换",那么你可能不会关心`std :: swap`是否比邪恶快速慢两倍. (8认同)
  • 编译器是否应该可以内联移动分配并删除死存储? (7认同)
  • @abigagli:lhs和rhs指针都需要加载到寄存器中.需要加载lhs以便可以检查并删除它.需要将rhs指针加载到寄存器中以将其存储到lhs(除非您的机器具有内存到内存的移动操作).lhs和rhs指针都需要一个新值,因此需要2个存储. (2认同)