Add elements to a vector during range-based loop c++11

后端 未结 2 1884
耶瑟儿~
耶瑟儿~ 2020-12-03 17:24

I have used the new range-based for loop provided by C++11 standard and I came up with the following question: suppose that we iterate over a vector<> usi

相关标签:
2条回答
  • 2020-12-03 18:03

    You can rely on this behavior as long as vector's capacity is large enough, so reallocation is not required. This would guarantee validity of all iterators and references other than past-the-end iterator after call to push_back(). This is fine since end() was calculated only once at the beginning of the loop (see std::vector::push_back).

    In your case, you have to increase capacity of test vector to guarantee this behavior:

    vector<unsigned> test({1,2,3});
    test.reserve(5);
    

    EDIT

    Based on responses to Is it legal to add elements to a preallocated vector in a range-based for loop over that vector?, this is a case of undefined behavior. Release version built with gcc, clang and cl runs fine, but a debug version built with cl (Visual Studio) will throw an exception.

    0 讨论(0)
  • 2020-12-03 18:14

    No you cannot rely on this behaviour. Modifying the vector inside the loop results in undefined behaviour because the iterators used by the loop are invalidated when the vector is modified.

    The range based for loop

    for ( range_declaration : range_expression) loop_statement
    

    is essentially equivalent to

    {
        auto && __range = range_expression ; 
        for (auto __begin = std::begin(__range),
            __end = std::end(__range); 
            __begin != __end; ++__begin) { 
                range_declaration = *__begin;
                loop_statement 
        }
    }
    

    When you modify the vector, the iterators __begin and __end are no longer valid and the dereferencing __begin results in undefined behaviour.

    0 讨论(0)
提交回复
热议问题