示例代码:
#include <iostream>
int main()
{
std::vector<int> w(20, 123), x;
w = std::move(w);
std::cout << w.size() << std::endl;
}
g ++ 4.8.3上的输出:0
当然,标准说移动赋值运算符使操作数处于未指定状态。例如,如果代码为x = std::move(w);
,那么我们希望w.size()
为零。
但是,是否有指定的排序或其他条款涵盖自行案例?是否未指定大小是0
还是20
,还是其他内容,或未定义的行为?标准容器在这里有任何定义的语义吗?
相关:this thread讨论你是否应该关心你自己的类中的自行移动,但不讨论标准容器的移动赋值操作符是否这样做,并且不提供标准引用。
NB。这与w = static_cast< std::vector<int> && >(w);
完全相同,或者std::move
是一个函数是否会产生影响?
答案 0 :(得分:6)
§17.6.4.9[res.on.arguments]:
以下各项适用于C ++标准库中定义的函数的所有参数,除非另有明确说明。
- [...]
- 如果函数参数绑定到右值引用参数,则实现可以假设 此参数是对此参数的唯一引用。 [注意:如果参数是
T&&
形式的通用参数并且绑定了类型A
的左值,则参数绑定到左值引用(14.8.2.1),因此不包括上一句。 - 结束注释] [注意:如果程序在将左值传递给库函数时将左值转换为x值(例如通过调用带有参数move(x)
的函数),程序实际上是要求该函数来处理左值作为临时值。实现可以自由地优化别名检查,如果参数是左值,则可能需要这些检查。 - 尾注]
由于“实现可能会假设此参数是对此参数的唯一引用”,并且自移动赋值会违反此假设,因此它具有未定义的行为。