我有一个std::vector
的包装器,我已经实现了一个函数,用另一个向量替换向量中的一个部分。 我试图将迭代器的赋值直接置于if
条件并获得意外结果。
我使用Visual Studio 2013并定义FAIL
我得调试断言失败! - 矢量迭代器不兼容。是否有可能从右到左评估病情?我无法克服它。
这是一个(执行不佳)代码,它可以重现我的问题 - 用vec
的第一和第二个元素替换vec_second
的第三和第四个元素:
#include <iostream>
#include <vector>
#include <iterator>
using std::cout;
//#define FAIL
int main()
{
std::vector<int> vec = {1, 2, 3, 4, 5};
std::vector<int> vec_second = {6, 7};
auto it = vec.begin() + 2;
#ifndef FAIL
it = vec.erase(it, it + vec_second.size());
if(it == vec.end())
#else
if((it = vec.erase(it, it + vec_second.size())) == vec.end())
#endif
vec.reserve(vec.size() + vec_second.size());
vec.insert(it, vec_second.begin(), vec_second.end());
for(auto const& x : vec)
cout << x << " ";
}
但在Coliru's GCC上运行良好。
答案 0 :(得分:7)
if((it = vec.erase(it, it + vec_second.size())) == vec.end())
由于它们之间没有序列点,编译器可以任意顺序调用erase
和end
。如果首先调用end
,则erase
会立即使该迭代器失效,从而导致未定义的行为。
您的#ifndef FAIL
代码是安全的方法。