条件中的迭代器赋值 - 矢量迭代器不兼容

时间:2015-05-04 17:13:08

标签: c++ visual-studio-2013 iterator

我有一个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上运行良好。

1 个答案:

答案 0 :(得分:7)

if((it = vec.erase(it, it + vec_second.size())) == vec.end())

由于它们之间没有序列点,编译器可以任意顺序调用eraseend。如果首先调用end,则erase会立即使该迭代器失效,从而导致未定义的行为。

您的#ifndef FAIL代码是安全的方法。