What is the difference between iterator_category and iterator_concept in C++20?(在C++20中,迭代器类别和迭代器概念有什么不同?)
问题描述
C++20带来了更强大的iterator系统,其中之一就是在iterator_category的基础上引入iterator_concept。
我发现C++20中很多迭代器的iterator_concept和iterator_category不一致。将最著名的iota_view视为example:
using R = decltype(views::iota(0));
static_assert(random_access_range<R>);
using I = ranges::iterator_t<R>;
static_assert(same_as<typename I::iterator_category, input_iterator_tag>);
static_assert(same_as<typename I::iterator_concept, random_access_iterator_tag>);
虽然R模型random_access_range,但其迭代器的iterator_category只是一个input_iterator_tag,与iterator_concept不一致。
为什么C++20引入iterator_concept?它的目的是什么?如果我实现自己的迭代器,我如何正确定义iterator_concept和iterator_category?iterator_category在C++20中是否仍有意义?
推荐答案
C++17(C++98)迭代器模型和C++20 Ranges迭代器模型之间存在不向后兼容的差异。两个大问题是:
- C++98模型要求前向迭代器具有
value_type&或value_type const&。 - C++98模型不允许
contiguous迭代器。最强的类别是random_access。
(1)的结果非常重要-它意味着如果您有一个返回pr值的迭代器(无论是否代理引用),它永远不会比输入迭代器更强。因此,views::iota(1, 10)尽管能够轻松支持随机访问,但充其量也只是一个C++98输入范围。
iterator_category进行判断的现有代码完全有权假定,如果iterator_category是bidirectional_iterator_tag,则其reference是对value_type的某种左值引用。iterator_concept所做的是添加一个新的C++20层,它允许迭代器既宣传其C++98/17类别,又明确地宣传其C++20类别。因此,回到iota_view<int, int>示例,该视图的迭代器将iterator_category设置为input_iterator_tag(因为reference是一个pr值,因此它不满足甚至转发的旧要求),但它的iterator_concept被设置为random_access_iterator_tag(因为一旦我们放弃该限制,我们就可以轻松地支持所有随机访问限制)。
在[iterator.concepts.general]中,我们有一个神奇的函数ITER_CONCEPT(I),它帮助我们确定在C++20中使用什么标记。
(2)的问题是,由于各种C++98/17代码将检查该标记的方式(许多代码可能会准确地检查random_access_iterator_tag),因此很难在之前只添加一个新的contiguous_iterator_tag。iterator_concept方法通过引入直接为您检查正确事物的概念来避免此问题(即random_access_iterator概念检查ITER_CONCEPT(I)派生自random_access_iterator_tag,而不是简单地从random_access_iterator_tag派生)。
指南:
- 如果您正在使用C++17中的迭代器,请使用
std::iterator_traits<I>::iterator_category。 - 如果您在C++20中使用迭代器,请使用
std::meow_iterator概念 - 如果您要在C++17中编写迭代器,请添加
iterator_category别名,并确保遵循向前迭代器/引用限制(或...不要,但这是你的责任) - 如果您正在用C++20编写迭代器,请遵循P2259中的指导,该指南对问题以及如何以及何时提供
iterator_category和iterator_concept类型别名进行了很好的描述。
这篇关于在C++20中,迭代器类别和迭代器概念有什么不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:在C++20中,迭代器类别和迭代器概念有什么不同?
基础教程推荐
- 常量变量在标题中不起作用 2021-01-01
- 如何将 std::pair 的排序 std::list 转换为 std::map 2022-01-01
- 如何检查GTK+3.0中的小部件类型? 2022-11-30
- 静态库、静态链接动态库和动态链接动态库的 .lib 文件里面是什么? 2021-01-01
- 如何通过C程序打开命令提示符Cmd 2022-12-09
- C++结构和函数声明。为什么它不能编译? 2022-11-07
- 在 C++ 中计算滚动/移动平均值 2021-01-01
- 如何在 C++ 中初始化静态常量成员? 2022-01-01
- 这个宏可以转换成函数吗? 2022-01-01
- 我有静态或动态 boost 库吗? 2021-01-01
