为什么 STL 类 不为右值重载 swap()?

Why STL classes do not overload swap() for rvalues?

STL 类 将 swap() 方法定义为 void swap(A&),采用左值引用。例如参见 [​​=16=]".

这样的定义意味着我们不能与 r 值交换,因为 r 值不会绑定到 但是,我认为与 r 值交换没有坏处。建造它,窃取它,在其中放置一些胆量,摧毁它。完毕。我们可以添加另一个重载 void swap(A&&) 来实现它。

我只看到我们没有开箱即用的过载的一个原因。因为不是写

v.swap(rvalue);

最好写

v = rvalue;

我们将触发移动分配,而不是交换,这样效率更高。我认为这个理由有效吗?这是唯一的原因吗?

您或多或少已经回答了您自己的问题。

我们需要

  v.swap(rvalue);

在通往 C++11 的黯淡 dark-ages 中。从那时起,我们可以明确地获取右值来为所欲为。

允许swap取右值将是倒退

"moving" 的要点是,一旦您离开源,您就不再关心源的状态。这与 swap 完全不同,其中两个状态之后都是 well-defined。

IOW,A::swap(A&& rhs) 同时做但不保证 rhs 之后会处于什么状态。

最初的移动文件之一实际上为容器指定了这一点:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1858.html#23.2%20-%20Sequences

然后传播到 shared_ptrfunction

http://cplusplus.github.io/LWG/lwg-defects.html#743

http://cplusplus.github.io/LWG/lwg-defects.html#770

LWG 884 不支持右值参数交换:

http://cplusplus.github.io/LWG/lwg-defects.html#884

而 N2844 随后删除了 所有 右值交换:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2844.html

我不认为这是一个好举措。然而,使用更现代的 shrink_to_fit() 减少内存的方式,我不认为它很重要,因为这是与右值交换的主要用例。