07 | 迭代器和好用的新for循环
该思维导图由 AI 生成,仅供参考
什么是迭代器?
- 深入了解
- 翻译
- 解释
- 总结
C++中的迭代器是一个通用概念,允许对容器内元素进行遍历。C++17引入了更灵活的迭代器类型,包括输入迭代器、输出迭代器、前向迭代器、双向迭代器、随机访问迭代器和连续迭代器。文章介绍了如何定义输入行迭代器,以及如何使用基于范围的for循环语法简化遍历输入流的代码。通过示例代码和详细解释,读者可以更好地理解迭代器的概念和在实际编程中的应用。此外,文章还提供了相关的参考资料和课后思考问题,帮助读者进一步加深对迭代器的理解和应用。 文章内容涵盖了迭代器的基本概念、类型和实际应用,对于想要深入了解C++迭代器的读者来说,这篇文章提供了丰富的信息和实用的示例。同时,通过课后思考问题,读者还可以进行进一步的思考和讨论,加深对迭代器的理解。总的来说,这篇文章对于C++编程中迭代器的理解和应用具有很高的参考价值。
《现代 C++ 编程实战》,新⼈⾸单¥59
全部留言(34)
- 最新
- 精选
- 小一日一看了老师的代码再看自己学的代码,感觉我的C++是小学生水平。 以为自己看过几遍C++ PRIMER 5th, 看过并理解effective++, more effective c++, inside the c++ object model, 能应付平时的开发需要,也能看懂公司别人的代码,就觉得自己的C++不错了,看了老师github的代码后我是彻底服了,感叹C++太博大精深,永远不敢说自己精通C++。 我什么时候才能达到老师对C++理解并使用的高度呢,难道也需要20年么?
作者回复: 肯定还有更好的 C++ 代码的。学习无止境! 认真学习,应该不用那么久(我还没有极客时间专栏来帮助我学习呢😌)。 反过来,说明老程序员还有点价值么。🤗
2019-12-11429 - Geek_b68b741、使用输入行迭代器 这一部分里,“ auto&& r = istream_line_reader(is);” 这里为什么要用右值引用呢? 2、还是使用输入行迭代器这里, for (const string& line : istream_line_reader(is)) { // 示例循环体中仅进行简单输出 cout << line << endl; } “获取冒号后边的范围表达式的结果,并隐式产生一个引用,在整个循环期间都有效。注意根据生命期延长规则,表达式结果如果是临时对象的话,这个对象要在循环结束后才被销毁。” 第一句是说line在整个循环期间有效?这是想表达什么呢?还有第二句,指的是哪个临时对象呢?在哪个循环结束后销毁呢?期待您的解答
作者回复: 你的两个疑问实际是针对同一个地方。 auto&& 那句是用一个“万能”引用捕获一个对象,左值和右值都可以。C++ 的生命期延长规则,保证了引用有效期间,istream_line_reader 这个“临时”对象一直存在。没有生命期延长的话,临时对象在当前语句执行结束后即销毁。
2020-01-1739 - 千鲤湖过来看看老师问的那两个问题,好奇中。。。
作者回复: 公布第 1 个问题的答案吧: #include <fstream> #include <iostream> #include "istream_line_reader.h" using namespace std; int main() { ifstream ifs{"test.cpp"}; istream_line_reader reader{ifs}; auto begin = reader.begin(); for (auto it = reader.begin(); it != reader.end(); ++it) { cout << *it << '\n'; } } 以上代码,因为 begin 多调用了一次,输出就少了一行……
2019-12-188 - 禾桃输入迭代器和输出迭代器, 这个入和出是相对于什么而言的? 感觉有点绕。 谢谢!
作者回复: cout << *it 就是读; *it = 42 就是写。
2019-12-115 - Slience-0°C有个问题请教老师,工作中看到基于范围的for循环中,使用了auto &&来获取数据,而不是auto&,有啥区别么?难道是为了使用移动构造函数?伪代码如下:std::vectors<std::string> vec; for (auto&& : vec)
作者回复: auto&& 是转发引用(第 8 讲也会简单提到)。转发引用的概念在第 3 讲里提过(我可能会在第 37 讲再展开探讨一下),但在那里的形式是 T&&。 auto&& 能匹配所有的引用(const 左值、非 const 左值、右值等),使用正确的场景下后续应该使用 std::forward。如果你没看到后续用 std::forward,那这个使用很有可能不是最好的写法。根据你是否需要修改 vec 中的内容,auto& 或 const auto& 会更加明确。
2022-04-2164 - nelson如果stream_是nullptr会怎么样?
作者回复: 得到一个空的不能遍历的迭代器。跟任何 end() 相等比较返回真,因而你不可以对它做 ++ 操作。如果你要硬来,它就死给你看。
2019-12-1223 - EncodedStar课后思考 1.目前这个输入迭代器的行为,在干什么情况下可能导致意料之外的后果? 答:目前这个输入迭代器在构造里调用了++,所以,多一次构造就可能读到意料之外的结果了。 2.请尝试一下改进这个输入行迭代器,看看能不能消除这种意外,如果可以,该怎么做?如果不可以,为什么? 答:可以啊,文章里提到了,这个输入行迭代器构造的使用了++,是为了与日常使用一致,如果想改进这个一块,我们也可以改构造的时候
作者回复: 1 对。2 你需要自己实验一下,再想想会不会有其他副作用。
2019-12-242 - 旭东老师,您好,iterater中后置++的实现是不是应该返回const;避免(i++)++这样的代码通过编译?
作者回复: 1. 不能写 const,因为你修改了自己。 2. 就算能写也防不了,因为你返回的是个全新的对象。
2019-12-142 - 晚风·和煦从 C++17 开始,I 和 S 可以是不同的类型。这带来了更大的灵活性和更多的优化可能性。 没太理解这句话😂
作者回复: 现在 r.begin() 和 r.end() 可以是不同类型了。
2019-12-112 - doge第二个问题想了半天,好像做不到,根据begin的语义,拿到stream_对象后就必须取得第一行内容,否则返回的就是一个空string而不是文件的第一行。但是在iterator对象内好像没办法记录“第一次从strem_读”这样的一个状态。我尝试标记第一次,但是会忽视读的操作,这样还是会导致第一行内容的丢失。希望老师解惑。 explicit iterator(istream& is) : stream_(&is) {} iterator begin() { cout << "first_ = " << first_ << endl; if (first_) { first_ = false; return ++iterator(*stream_); } else { return iterator(*stream_); } }
作者回复: 对的,这题的目的就是让你理解目前这种做法实际还是个不错的折中。也可以参考一下参考答案那节。
2021-02-241