【问题标题】:Why STL classes do not overload swap() for rvalues?为什么 STL 类不会为右值重载 swap()?
【发布时间】:2016-01-24 18:30:19
【问题描述】:

STL 类将swap() 方法定义为void swap(A&),采用左值引用。例如见std::vector::swap,或这个问题“Is `std::move` necessary here?”。

这样的定义意味着我们不能与 r-values 交换,因为 r-value 不会绑定到 但是,我认为与 r-values 交换没有什么害处。建造它,偷取它,在里面放一些胆量,然后摧毁它。完毕。我们可以添加另一个重载void swap(A&&) 来实现它。

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

v.swap(rvalue);

最好写

v = rvalue;

我们将触发移动分配,而不是交换,这更加有效。我说这个理由是对的吗?这是唯一的原因吗?

【问题讨论】:

  • 为什么不写rvalue.swap(v)
  • @KerrekSB 对,如果我可以写rvalue.swap(v),为什么我不能写相反的? swap 操作是可交换的,所以我希望它可以通过两种方式访问​​。
  • 成员函数并不是真正可交换的。

标签: c++ c++11 swap


【解决方案1】:

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

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() 减少内存的方式,我并不肯定这很重要,因为这是与右值交换的主要用例。

【讨论】:

    【解决方案2】:

    你或多或少地回答了你自己的问题。

    我们需要

      v.swap(rvalue);
    

    在 C++11 之前的黯淡黑暗时代。从那时起,我们可以明确地抓住右值来做我们喜欢的事情。

    允许swap 采用右值将退后一步

    【讨论】:

      【解决方案3】:

      “移动”的意义在于,一旦你离开了源,你就不再关心它的状态。这与swap 完全不同,这两个状态在之后都是明确定义的。

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

      【讨论】:

      • 不同意。 A::swap(A&& rhs) 严格定义了调用后rhs 的状态。 rhs 在语句末尾自动销毁的事实在这里无关紧要。
      • @Mikhail:为什么A::swap(A&& rhs) 会严格定义移出变量的状态?您似乎正在引入一个特殊的成员函数,该函数不受移出变量处于未指定状态的规则的约束。
      • 好的,同意。我忘记了我们不能依赖这样一个事实,例如移出的向量是空的。
      猜你喜欢
      • 1970-01-01
      • 2015-06-01
      • 2013-05-13
      • 2012-02-08
      • 1970-01-01
      • 2012-01-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多