在基于范围的循环中向vector添加元素
Add elements to a vector during range-based loop c++11
我使用了c++ 11标准提供的新的基于范围的for循环,我提出了以下问题:假设我们使用基于范围的for
迭代vector<>
,并且我们在迭代期间在向量的末尾添加一些元素。因此,循环何时结束?
例如:
#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;
}
我用"-std=c++11"标志测试了g++ 4.8和Apple LLVM版本4.2 (clang++),输出如下:
1 2 3
1 2 3 11 13
注意,第一个循环终止于原vector的末尾,尽管我们向其中添加了其他元素。for-range循环似乎只对容器的开始结束进行求值。事实上,这是range-for的正确行为吗?是委员会指定的吗?我们能相信这种行为吗?
注意,如果我们将第一个循环更改为for(vector<unsigned>::iterator it = test.begin(); it != test.end(); ++it)
无效的迭代器,并出现分段错误。
不,你不能依赖这种行为。在循环内部修改vector会导致未定义的行为,因为当vector被修改时,循环使用的迭代器失效。
基于for循环的范围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
}
}
当你修改vector时,迭代器__begin
和__end
不再有效,解引用__begin
会导致未定义的行为。
只要vector的容量足够大,就可以依赖此行为,因此不需要重新分配。这将保证所有迭代器和引用的有效性,除了调用push_back()
之后的过端迭代器。这是可以的,因为end()
只在循环开始时计算一次(参见std::vector::push_back)。
在你的情况下,你必须增加test
向量的容量来保证这种行为:
vector<unsigned> test({1,2,3});
test.reserve(5);
编辑
基于以下问题的回应:在基于范围的for循环中向预分配的vector添加元素是否合法?,这是一个未定义行为的例子。使用gcc、clang和cl构建的发布版本运行良好,但使用cl (Visual Studio)构建的调试版本将抛出异常。
相关文章:
- 在某些循环内使用vector.push_back时出现分段错误
- 循环中的条件:为什么每次都调用strlen(),而vector.size()只调用一次
- 为什么 GCC 不能假设 std::vector::size 在这个循环中不会改变?
- 在 C++ 中使用 Vector 在动态数组中插入值,循环
- 在循环条件中调用const vector size()似乎缺少优化
- std::vector上的嵌套循环
- 使用虚拟变量对 std::vector 内部循环进行切片的最佳方法
- 访问类的 std::vector 与 for 循环中的 custum 类对象
- 如何在重复循环中循环遍历 std::vector
- 在基于范围的循环中使用shared_ptr到std :: vector
- 使用 std::vector<Particle> 粒子;函数 .at() 不能与迭代器一起使用,它作为 for 循环中的参数
- 在<Object>基于范围的 for 循环中从 std::vector 获取指向对象的指针
- 循环,直到没有遇到 std::vector 的任何元素
- 为什么 vector.clear() 在循环中不起作用?
- 循环浏览捕获的图像 vector<cv::Mat>
- std::vector< MyObj* > to std::vector< MyObj Const * >,如何无循环?
- 如何使用单 for 循环遍历 std::map<string>int 和 std::vector<int>?
- 为什么 vector::clear 在 foreach 循环中不起作用
- 使用auto循环vector时使用子类成员
- 在c++中循环vector会导致无效的迭代