现代 C++ 编程实战
吴咏炜
前 Intel 资深软件架构师
34196 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 51 讲
加餐 (1讲)
现代 C++ 编程实战
15
15
1.0x
00:00/00:00
登录|注册

29 | Ranges:无迭代器的迭代和更方便的组合

引用文章
非标 range-v3 库
批评观点
range-v3
Iterators must go
Boost.Range
名空间内容
性能分析
Python 代码对比
容器和视图满足的概念
Sentinel
Input_range
Output_range
Sized_range
Common_range
View 定义
Range 定义
视图示例
代码示例
参考资料
课后思考
内容小结
批评和未来
一点历史
ranges 名空间
抽象和性能
概念测试
范围相关的概念
Ranges 简介
Ranges

该思维导图由 AI 生成,仅供参考

你好,我是吴咏炜。
今天,我们继续上一讲开始的话题,讨论 ranges(范围)。

Ranges 简介

像下面这样的代码:
#include <algorithm>
#include <iostream>
#include <iterator>
int main()
{
using namespace std;
int a[] = {1, 7, 3, 6,
5, 2, 4, 8};
copy(begin(a), end(a),
ostream_iterator<int>(
std::cout, " "));
std::cout << std::endl;
sort(begin(a), end(a));
copy(begin(a), end(a),
ostream_iterator<int>(
std::cout, " "));
std::cout << std::endl;
}
你应该已经见到过好多次了。有没有觉得这个代码有点重复、有点无聊呢?尤其是里面的 beginend
很多人都留意到了迭代器虽然灵活,但不是一个足够高级的抽象——尤其是我们已经对 C 数组都可以进行基于“范围”的循环之后。如果我们把数组看作一个抽象的“范围”,我们就可以得到下面的代码:
#include <experimental/ranges/algorithm>
#include <experimental/ranges/iterator>
#include <iostream>
int main()
{
using namespace std::
experimental::ranges;
int a[] = {1, 7, 3, 6,
5, 2, 4, 8};
copy(a, ostream_iterator<int>(
std::cout, " "));
std::cout << std::endl;
sort(a);
copy(a, ostream_iterator<int>(
std::cout, " "));
std::cout << std::endl;
}
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

C++20引入了ranges库,为迭代和组合提供更便捷的方式,使代码更简洁高效。文章首先展示了传统迭代器的使用方式,然后介绍了ranges库的基本用法,重点介绍了视图的概念以及反转、过滤和组合操作的使用方法。此外,还介绍了ranges库中的一些概念,如range、view、common_range、sized_range等,并解释了它们的定义和用法。文章还介绍了Sentinel的概念,并通过示例代码展示了如何使用Sentinel来定义特定的结束条件。作者还讨论了ranges的抽象和性能,以及ranges命名空间的内容。文章最后提到了对ranges的批评和未来发展方向。总的来说,本文通过清晰的示例代码和概念解释,使读者能够快速了解C++中ranges库的基本特点和用法,以及对其批评和未来发展的展望。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《现代 C++ 编程实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(5)

  • 最新
  • 精选
  • pedro
    老师能讲一讲关于c++内存安全相关的编码规范和技巧吗,我觉得这个或许才是很多同学的刚需

    作者回复: 这个我没想到很简单的讲法。 不过,真要从简的话,最基本的要求就是,不要用 new,不要用裸指针:使用智能指针来代替。 此外,在用到视图的时候,包括 ranges 里的视图和更简单的情况如 string_view,要确保使用视图时视图使用的对象一直存在,没有被意外销毁。视图不管理内存。

    2020-02-07
    5
  • Geek_a16bbc
    template bool operator!=(I i, null_sentinel) { return *i != 0;} 可以請老師說明一下null_sentinel在這邊的作用嗎?function body並沒有用到null_sentinel, null sentinel只出現在input parameter上。

    作者回复: 循环展开后,会有相当于下面的表达式: auto it = argv[1]; auto end = null_sentinel(); while (it != end) { … ++it; } 这样不就用上上面的 operator!= 了?

    2020-10-13
    3
  • 三味
    emmmmmmm... 最后提到的这篇文章,我之前看到过,印象最深刻的一句话就是,没有C++博士学位还想写C++? 最近的未来篇三篇我基本上都是走马观花的在看。。对我个人来说,感觉收益和学习成本比值有点小,根据以往经验,C++20要想全面开花,还有好几年的路要走。。 感觉C++11也是到了C++14才算是稳定点。。至少给我的感觉,直到C++17都是在对C++11进行修补。 所以,这三讲一年后我再回来好好学习吧!本来我的主业是图形

    作者回复: 看这些内容对你潜在是否有用吧。(我不是博士,也不喜欢太烧脑的代码。) 个人认为概念很重要,可能会改变大家对 C++ 的写法。协程对异步处理很重要,看你是不是需要了。范围是个好玩的东西,但如果对它不感冒,放一放关系也不大。 另外,那篇文章的作者的措辞是“像我们一样的没有C++博士学位的凡人”,哈哈。而且,他也说“‘coroutines’方法更清晰”。 出于好奇,我又去查了下 Eric Niebler 的简历,结果发现他也不是博士。他甚至不是计算机系毕业的(而是机械工程)。但他在 C++ 上浸淫的时间就长了(96 年毕业直接去了微软 Visual C++ 组),而且他还喜欢函数式编程。他认为容易的东西,别人理解有困难,也不算很不正常了。

    2020-02-11
    3
  • Sochooligan
    一、看得云里雾里地,好的方面是所有例子都运行了。 二、发现两处分心的地方: (1)我们可以在输出 r 之前插入下面这行: 我们可以在输出 r 之前(15行之后,16行之前)插入下面这行: (2)除了 view,vector 满足所有的 range 概念。 vector 满足除view外所有的 range 概念。 三、我的环境是 macOS+vscode+gcc9.2.0_3(Target: x86_64-apple-darwin19) +gdb8.3

    作者回复: 多看两遍。ranges 和 concepts 对于一般的开发者来说应当是很新的东西,我自己也学习了很多遍,踩了很多坑。 二(1) 加行号说明是个好主意,我改一下吧。二(2) 两可之间的,就不动了。

    2020-02-08
    2
  • 皮皮侠
    我大概能理解Bjarne Stroustrup最喜欢的C++特性为何有concepts:在高度统一的抽象中去繁就简。也在网上看了些对C++20中Ranges的反对意见,但我看到很多游戏开发者倒很喜欢这些新功能,感觉大多容器都能用ranges;)听老师读的那段,真是激情澎湃,魅力四射!

    作者回复: 哈哈😇

    2020-03-02
收起评论
显示
设置
留言
5
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部