标准库对自动分配的保证是什么?

时间:2012-10-29 18:23:22

标签: c++ stl c++11 move-semantics

C ++ 11标准对标准库中的自移动赋值有何看法?更具体一点是,selfAssign做什么可​​以保证什么呢?

template<class T>
std::vector<T> selfAssign(std::vector<T> v) {
  v = std::move(v);
  return v;
}

2 个答案:

答案 0 :(得分:33)

17.6.4.9函数参数[res.on.arguments]

  

1以下各项适用于定义的函数的所有参数   除非另有明确说明,否则在C ++标准库中。

     

...

     
      
  • 如果函数参数绑定到右值引用参数,则实现可以假定此参数是对其的唯一引用   这个论点。 [注意:如果参数是通用参数   形式T&amp;&amp;并且绑定了一个类型A的左值,该参数绑定到一个   左值参考(14.8.2.1)因此不在前面   句子。 - 结束注释] [注意:如果程序将左值转换为   将左值传递给库函数时的xvalue(例如通过   用参数move(x)调用函数,程序是   有效地要求该函数将该左值作为临时值处理。   实现可以自由地优化别名检查   如果参数是anlvalue可能需要。 -endnote]
  •   

因此,允许std::vector<T, A>::operator=(vector&& other)的实现假设other是prvalue。如果other是prvalue,则无法进行自动分配。

可能发生的事情:

v将处于无资源状态(0容量)。如果v已经有0容量,那么这将是一个无操作。

<强>更新

latest working draft, N4618已被修改,以明确说明MoveAssignable要求中的表达式:

t = rv

(其中rv是右值),如果trv没有t,则rv只需要在分配之前为rv的等效值引用相同的对象。无论如何,rv的状态在分配后未指定。还有一个说明需要进一步澄清:

  无论trv是否引用相同的对象,

{{1}}仍必须满足使用它的库组件的要求。

答案 1 :(得分:0)

a relevant post by Eric Niebler 有多个链接,例如到this answer by Howard Hinnant

最新的 С++20 工作草案(N4861)在我看来仍然有些模棱两可。但是,最近有一个 Library Working Group issue 2839[lib.types.movedfrom]/2 中添加了以下显式语句:

<块引用>

在 C++ 标准库中定义的类型的对象可以移动分配 (11.4.6 [class.copy.assign]) 给自身。除非另有说明,否则这种赋值会将对象置于有效但未指定的状态。

它已经在 C++23 的 N4885 工作草案中了。

因此,selfAssign 保证不会导致未定义的行为,并且由于 std::vector 没有额外的保证,因此将 v 保留在某个有效状态。