在基于范围的循环 c++11 期间将元素添加到向量 [英] Add elements to a vector during range-based loop c++11

查看:42
本文介绍了在基于范围的循环 c++11 期间将元素添加到向量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用了 C++11 标准提供的新的基于范围的 for 循环,并提出了以下问题:假设我们使用范围迭代 vector<>-基于 for,我们在这个迭代过程中在向量的末尾添加了一些元素.因此,循环何时结束?

例如,看这个代码:

#include #include <向量>使用命名空间标准;int main() {向量<无符号>测试({1,2,3});for(auto &num : test) {cout<<数量<<"";如果(数量 % 2)test.push_back(num + 10);}cout<<"
";for(自动&num : 测试)cout<<数量<<"";返回0;}

我使用-std=c++11"标志测试了 G++ 4.8 和 Apple LLVM 版本 4.2 (clang++),输出是(对于两者):

1 2 31 2 3 11 13

请注意,尽管我们向其中添加了其他元素,但第一个循环在原始向量的末尾终止.似乎 for-range 循环仅在开始时评估容器结束.事实上,这是 range-for 的正确行为吗?是否由委员会指定?我们可以相信这种行为吗?

注意,如果我们改变第一个循环

for(vector::iterator it = test.begin(); it != test.end(); ++it)

迭代器无效并产生分段错误.

解决方案

不,您不能依赖这种行为.修改循环内的向量会导致未定义的行为,因为当修改向量时,循环使用的迭代器会失效.

基于范围的for循环

for ( range_declaration : range_expression) loop_statement

本质上等同于

{汽车&&__range = range_expression ;for (auto __begin = std::begin(__range),__end = std::end(__range);__开始!= __结束;++__开始){range_declaration = *__begin;循环语句}}

当您修改向量时,迭代器 __begin__end 不再有效并且取消引用 __begin 会导致未定义的行为.

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<> using the range-based for, and we add some element in the end of the vector during this iteration. Thus, when do the loop end?

For instance, see this code:

#include <iostream>
#include <vector>
using namespace std;
int main() {
    vector<unsigned> test({1,2,3});
    for(auto &num : test) {
        cout << num << " ";
        if(num % 2)
            test.push_back(num + 10);
    }
    cout << "
";
    for(auto &num : test) 
        cout << num << " ";
    return 0;
}

I tested G++ 4.8 and Apple LLVM version 4.2 (clang++) with "-std=c++11" flag, and the output is (for both):

1 2 3
1 2 3 11 13

Note that the first loop terminates in the end of original vector, although we add other elements to it. It seems that the for-range loop evaluate the container end in beginning only. Is this, in fact, the correct behavior of range-for? Is it specified by the committee? Can we trust in this behavior?

Note that if we change the first loop by

for(vector<unsigned>::iterator it = test.begin(); it != test.end(); ++it)

with invalid the iterators and come up with a segmentation fault.

解决方案

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.

这篇关于在基于范围的循环 c++11 期间将元素添加到向量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆