简体   繁体   中英

C++ iterator as argument in lambda function, assertion failed: “vector iterators incompatible”

I encountered a strange behavior after calling an lambda function with iterator as argument. It produces an assertion fail "vector iterators incompatible".

My code looks something like this:

std::vector<LAYOUT> Layouts;
// fill vector...
auto it = Layouts.begin();
while (it != Layouts.end()) {
    // do something...
    auto fn= [Layouts] (auto i) -> void {
        while (i != Layouts.end()) { // <- ASSERTION RAISED HERE
            // do something...
            i++;
        }
    };
    fn(it);
    it++;
}

The assertion is raised in vector.h in

void std::_Vector_const_iterator<_Myvec>::_Compat(const _Myiter& _Right) const {
// test for compatible iterator pair
    if (this->_Getcont() != _Right._Getcont()) {
        _DEBUG_ERROR("vector iterators incompatible");
        _SCL_SECURE_INVALID_ARGUMENT;
    }
}

The question is why does this happen?

I took me a while to find the real problem here. The solution is simple: Layouts was not passed as reference in capture clause. So a copy of that vector was generated first. Then it is clear to understand that Layouts.end() iterator was no more compatible with the original vector iterator given as argument in lambda function.

The solution is to add the reference operator (&) in capture clause.

auto fn= [&Layouts] (auto i) -> void {
    while (i != Layouts.end()) {
        // do something...
        i++;
    }
};

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