C++ 语言中的for循环怎么用
Tofloor
poster avatar
loufand
deepin
2020-07-30 02:24
Author
今天突然发现我不知道for循环怎么用了,请论坛大佬指点一下

下面这段代码会怎么执行?
  1. std::vector vec = {1, 2, 3, 4, 5, 6, 7};
  2.     for (auto &&i : vec)
  3.     {
  4.         std::cout << " :" << i << "    ";
  5.         vec.push_back(i * 10);
  6.         std::cout << vec.size() << std::endl;
  7.     }
Copy the Code


我的问题是:
C++11中的范围for循环,for(declaration : expression)
expression会被执行几次?只有在第一次进入时执行么?
经过实验发现是的,但是我没有在资料中查到具体描述。
Reply Favorite View the author
All Replies
avatar
loufand
deepin
2020-07-30 02:25
#1
还是说上面的代码未定义行为啊?
Reply View the author
avatar
jzc
deepin
2020-07-30 02:48
#2
for (auto &&i : vec)   有问题,   改成   for (auto &i : vec)   
Reply View the author
avatar
loufand
deepin
2020-07-30 02:58
#3
https://bbs.deepin.org/post/197858
for (auto &&i : vec)   有问题,   改成   for (auto &i : vec)

这有什么问题?右值引用不行么?
Reply View the author
avatar
jzc
deepin
2020-07-30 03:59
#4
我刚才搞错了。原因是在循环体内改变了vec的元素个数,   vec.push_back(i * 10);    数组的长度发生了变化
Reply View the author
avatar
jzc
deepin
2020-07-30 04:04
#5
c++ primer  5th   169页, 指出了你的问题 。 范围 for 语句内部使用的是迭代器。你改变vector 长度,迭代器会发生变化
Reply View the author
avatar
jzc
deepin
2020-07-30 04:16
#6
本帖最后由 jzc 于 2020-7-29 21:01 编辑

还有,右值引用一般不这么用。它是用在 右值(无法取得地址)+ 临时对象(即将被销毁)+ 需要支持移动语义的 情况下。
Reply View the author
avatar
jzc
deepin
2020-07-30 04:22
#7
我建议你把 c++ primer  5th   向量、容器、迭代器、右值引用、move语义、移动构造、移动赋值  这些章节看看
Reply View the author
avatar
ritter
deepin
2020-07-30 04:41
#8
for range算是syntactic sugar,其实跟for(auto i = vec.begin(); i != vec.end(); i++)一模一样,汇编代码没有任何区别。在for循环中,vec给你一个迭代器,vec.end()在编译时就已经确定,所以即使你在过程中改变了vector的长度,for循环中并不知道,他还是按照原来的vec.end()进行循环。

而且这代码有严重的内存管理问题,std::vector的使用的技术是整体拷贝,不是链表,当你初始化vector的时候,他的capacity是7。当你在for循环中第一次pushback后,vec由于capacity不够了,就重新申请7*2*sizeof(int)的内存,然后把原来的vec拷贝到新的内存,然后再pushback,现在新的capacity就是14了,原来的内存就被丢弃了。在你的代码中,for循环中打印出来的数字都是在最初的内存上遗留下来的东西,所以不一定是原来的数字,也可能是乱码,这就是说,for循环中的迭代器相当于一个野指针了。

但是你如果使用链表技术的容器(比如list)来做相同的事情,由于链表不是连续地址,所以for循环永远碰不到vec.end(),所以最终一定进入死循环,你不信可以试试。
Reply View the author