std::move在vector::insert和push_back上的行为不同
std::move behaves differently on vector::insert and push_back
我注意到vector::push_back
和insert
之间的行为有差异。
当我做时
iter = myVector.begin() + 5;
myVector.push_back(std::move(*iter));
矢量中的第6个元素被添加到底部,并从上一个位置删除。
然而,如果我这样做:
iterBegin = myVector.begin();
myVector.insert(iterBegin,std::move(*(iterBegin + 5)));
第6个元素被插入到第一个位置,但它不会从上一个位置删除。
为什么std::move
在insert()
中不能像在push_back()
中那样工作?
17.6.4.9函数参数/res.on.arguments]/p1/b3表示:
1以下各项适用于定义的函数的所有参数在C++标准库中,除非另有明确说明。
- 如果函数参数绑定到右值引用参数,则实现可能会假设此参数是对的唯一引用这个论点。注意:如果参数是形式为
T&&
且类型为A
的左值绑定,则参数绑定左值参考(14.8.1.1),因此不在上一句。——结束注释][注释:如果程序强制转换将左值传递到xvalue,同时将该左值传递给库函数(例如,通过调用参数为move(x)
的函数)程序正在请求该函数将该左值视为短暂的该实现可以免费优化消除混叠检查如果参数是左值,则可能需要它尾注]
简而言之,vector假定insert
和push_back
中&&
引用的自变量是临时的,因此不进行预防性混叠检查。
事实证明,假设您插入或推回了一个左值,push_back
算法无论如何都不需要检查混叠。然而,insert
算法确实如此(我具体指的是vector
,而不是其他容器)。因此,当您使用move
时,您不会注意到push_back
上缺少混叠检查,因为它们无论如何都不会有什么不同。然而,您确实注意到insert
上缺少它们。
迭代程序只有在集合类有效的情况下才有效,在这种情况下vector
没有被修改。一旦第一次插入,就会使迭代器无效,结果是未定义的。
因此,在任何一种情况下,iter
都会失效,并且会发生不好的事情!或者更糟的是,它似乎可以工作,除了发布版本,或者在那台旧机器上,或者当月亮满月时,等等。
相反,可以考虑将要添加的元素复制到新容器中,然后添加它们。
相关文章:
- 推导 std::vector::back() 的返回类型
- vector.back() 和 vector[vector.size() - 1] 之间的区别?
- vector.push_back(vector.back()+1) 是未定义的行为吗?
- C++自己的对象堆栈.在 push() 上复制了什么?
- C++ push() 和 pop() 方法使用指针的动态 LinkedList 的问题
- 如何像在javascript中一样"push" c ++映射
- 线路抑制状态错误 C4703 可能未初始化的局部指针变量"back"已使用
- std::vector using back(), pop_back(), push_back(), 得到'double free or corruption'错误
- vector.back()和vector.end()有什么区别
- 列表大小为 1,但 front() 和 back() 不相等
- 返回C++中没有 back() 方法的容器的最后一个元素?
- 在非空 std::list 上使用 std::list.back<int>() 时"Segmentation Fault"
- 模板堆栈类的复制构造函数中的 pop() 和 push() 不起作用
- 我们可以使用Back() - 值索引在其上执行向量插入
- 当我运行以下代码添加str.front() str.back时,它给了我200个,但为什么
- push(ing)back在循环中对象指针
- 在 C++ 中将元素添加到空向量:为什么 push.back 有效而 [] 无效
- 我似乎无法让 v.push.back() 处理字符串
- String::push_back() does not push back
- 向量resize(), push.back(), reserve()方法