0

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()像 in 一样工作push_back()

4

2 回答 2

3

17.6.4.9 函数参数 [res.on.arguments]/p1/b3 说:

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

...

  • 如果函数参数绑定到右值引用参数,则实现可能假定此参数是对该参数的唯一引用。[注意:如果参数是表单的泛型参数T&&并且绑定了类型的左值A,则参数绑定到左值引用(14.8.2.1),因此上一句未涵盖。— end note ] [注意:如果程序将左值转换为 xvalue,同时将该左值传递给库函数(例如,通过使用参数调用函数move(x)),则程序有效地要求该函数将该左值视为临时值。如果参数是左值,则该实现可以免费优化别名检查,这可能需要。—尾注]

简而言之,vector 假定&&两者都引用insert的参数push_back是临时的,因此不会进行预防性别名检查。

事实证明,假设您插入或 push_back'd 一个左值,该push_back算法无论如何都不需要检查别名。但是该insert算法确实如此(我特别指的是vector,而不是其他容器)。因此,当您使用 时move,您不会注意到缺少别名检查push_back,因为它们无论如何都不会产生影响。但是,您确实注意到缺少它们insert

于 2013-07-26T14:24:42.910 回答
1

迭代器仅在集合类(在这种情况下vector未修改)时才有效。一旦你第一次插入,你的迭代器就会失效并且结果是不确定的。

所以在任何一种情况下,iter都会变得无效并且会发生坏事!或者更糟糕的是,它似乎在发布版本、一台旧机器或满月等情况下都可以工作。

相反,请考虑将要添加的元素复制到新容器中,然后添加它们。

于 2013-07-26T05:30:47.307 回答