問題描述
我使用了 C++11 標(biāo)準(zhǔn)提供的新的基于范圍的 for 循環(huán),并提出了以下問題:假設(shè)我們使用范圍迭代 vector<>
-基于 for
,我們在這個迭代過程中在向量的末尾添加了一些元素.因此,循環(huán)何時結(jié)束?
例如,看這個代碼:
#include #include <向量>使用命名空間標(biāo)準(zhǔn);int main() {向量<無符號>測試({1,2,3});for(auto &num : test) {cout<<數(shù)量<<"";如果(數(shù)量 % 2)test.push_back(num + 10);}cout<<"
";for(自動&num : 測試)cout<<數(shù)量<<"";返回0;}
我使用-std=c++11"標(biāo)志測試了 G++ 4.8 和 Apple LLVM 版本 4.2 (clang++),輸出是(對于兩者):
1 2 31 2 3 11 13
請注意,盡管我們向其中添加了其他元素,但第一個循環(huán)在原始向量的末尾終止.似乎 for-range 循環(huán)僅在開始時評估容器結(jié)束.事實上,這是 range-for 的正確行為嗎?是否由委員會指定?我們可以相信這種行為嗎?
注意,如果我們改變第一個循環(huán)
for(vector::iterator it = test.begin(); it != test.end(); ++it)
迭代器無效并產(chǎn)生分段錯誤.
不,您不能依賴這種行為.修改循環(huán)內(nèi)的向量會導(dǎo)致未定義的行為,因為當(dāng)修改向量時,循環(huán)使用的迭代器會失效.
基于范圍的for循環(huán)
for ( range_declaration : range_expression) loop_statement
本質(zhì)上等同于
{汽車&&__range = range_expression ;for (auto __begin = std::begin(__range),__end = std::end(__range);__開始!= __結(jié)束;++__開始){range_declaration = *__begin;循環(huán)語句}}
當(dāng)您修改向量時,迭代器 __begin
和 __end
不再有效并且取消引用 __begin
會導(dǎo)致未定義的行為.>
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.
這篇關(guān)于在基于范圍的循環(huán) c++11 期間將元素添加到向量的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!