简体   繁体   中英

Iterator assignment in a condition - vector iterators incompatible

I have a wrapper for std::vector and I've implemented function that replaces a section within a vector with another vector. I've tried to put the assignment of an iterator directly in the if condition and got unexpected results .

I'm using Visual Studio 2013 and with FAIL defined I get Debug Assertion Failed! - vector iterators incompatible . Is it possible that the condition is being evaluated from right to left? I can't get over it.

This is a (poorly implemented) code that reproduces my problem - meant to replace 3rd and 4th elements of vec with 1st and 2nd elements of 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 << " ";
}

But runs fine on Coliru's GCC .

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

Since there is no sequence point between them, a compiler is free to call erase and end in either order. If end gets called first, that iterator is immediately invalidated by erase , leading to undefined behavior.

Your #ifndef FAIL code is the safe way to do this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM