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

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

问题描述

我使用了由C ++ 11标准提供的新的基于范围的for循环,我想出了以下问题:假设我们迭代向量<> 使用基于范围的替换,并且在此迭代期间在向量的末尾添加一些元素。因此,循环何时结束?



例如,请参阅以下代码:

  #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;
}

我测试了G ++ 4.8和Apple LLVM 4.2版(clang ++) = c ++ 11标志,输出为(对于两者):

  1 2 3 
1 2 3 11 13

请注意,第一个循环终止于原始向量的末尾,到它。看起来,范围循环仅在开始时评估容器末尾。
这是事实上,range-for的正确行为吗?是委员会指定的吗?我们可以相信这种行为吗?



请注意,如果我们改变

的第一个循环。

 code> for(vector< unsigned> :: iterator it = test.begin(); it!= test.end(); ++ it)
解决方案

$ p>

>没有你不能依赖这种行为。修改循环内的向量会导致未定义的行为,因为循环所使用的迭代器在向量修改时无效。



基于循环的范围

  for(range_declaration:range_expression)loop_statement 

本质上等效于

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

迭代器 __ 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 << "\n";
    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天全站免登陆