移动赋值给self的行为
Behaviour of move-assignment to self
示例代码:
#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
,或其他东西,或未定义的行为?标准容器在这里有任何定义的语义吗?
相关:这个线程讨论你是否应该关心自己的类中的自移动,但不讨论标准容器的移动赋值操作符是否这样做,并且不提供标准引用。
NB。这与w = static_cast< std::vector<int> && >(w);
完全相同,还是std::move
是一个函数的事实有所不同?
§17.6.4.9 [res.on.arguments]:
下列各项适用于c++标准库中定义的函数的所有实参,除非另有明确说明:
- […]
- 如果函数实参绑定到右值引用形参,则实现可以假定此形参是对该实参的唯一引用。[注:如果形参是
T&&
形式的泛型形参,并且绑定了A
类型的左值,则实参绑定到左值引用(14.8.2.1),因此不包括在前面的句子中。]注:如果一个程序在将左值传递给库函数的同时将左值强制转换为xvalue(例如,通过调用带参数move(x)
的函数),该程序实际上是在要求该函数将该左值视为临时值。该实现可以自由地优化掉在参数为左值时可能需要的混叠检查。
由于实现可能假设该形参是对该实参的唯一引用,而自移动赋值会违反此假设,因此它具有未定义行为。
参见LWG issue 1204
相关文章:
- 为"adjacent"变量赋值时出现问题
- C++中的赋值发生,尽管右侧出现异常
- 用C++中的sscanf赋值
- 为std::string的某个索引赋值
- 重载Singly Linked List中的赋值运算符
- 为什么我必须在C++中添加一个赋值符号来声明一个数组
- gtest_使用setargpointee在函数中赋值
- 非常量变量只读位置的赋值
- 使用赋值运算符重载从类中返回jobject
- C++数据文件、数组和计算赋值
- 为什么在使用转换构造函数赋值后调用C++类的析构函数?
- 全局作用域中函数指针的赋值
- 错误:在为指针赋值时,void值没有被忽略
- 标准库类型的赋值运算符的引用限定符
- 关于 c++ 函数中指针赋值的简单问题
- 复制构造函数、赋值运算符C++
- 标准::变体的赋值运算符
- 移动赋值给self的行为
- 有效的c++项目11处理对self的赋值
- c++中带self的复合赋值操作符