首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >iterator_category和iterator_concept在C++20中有什么区别?

iterator_category和iterator_concept在C++20中有什么区别?
EN

Stack Overflow用户
提问于 2021-05-19 15:46:06
回答 1查看 703关注 0票数 11

C++20带来了一个功能更强大的迭代器系统,其中之一就是在iterator_category的基础上引入iterator_concept

我发现许多迭代器的iterator_conceptiterator_category在C++20中是不一致的。以最著名的iota_view作为示例

代码语言:javascript
复制
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_conceptiterator_categoryiterator_category在C++20中还有意义吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-05-19 15:57:54

C++17 (C++98)迭代器模型与C++20 Ranges模型之间存在不向后兼容的差异。这两大问题是:

  1. C++98模型要求前向迭代器具有一个reference,即value_type&value_type const&
  2. C++98模型不允许contiguous迭代器。最强的类别是random_access

(1)的结果是相当重要的--这意味着如果您有一个返回prvalue的迭代器(无论代理引用与否),它永远不会比输入迭代器强。因此,尽管views::iota(1, 10)很容易支持随机访问,但充其量只能是一个C++98输入范围。

但是你不能就这样..。删除此要求。假设C++98迭代器并使用iterator_category进行判断的现有代码完全可以假定,如果iterator_categorybidirectional_iterator_tag,那么它的reference是某种对value_type的独立引用。

iterator_concept所做的是添加一个新的C++20层,允许迭代器同时为其C++98/17类别做广告,并清楚地为其C++20类别做广告。因此,回到iota_view<int, int>示例,该视图的迭代器将iterator_category设置为input_iterator_tag (因为reference是一个prvalue,因此它不能满足以前的转发要求),但它的iterator_concept设置为random_access_iterator_tag (因为一旦我们删除了该限制,我们就可以轻松地支持所有随机访问限制)。

[iterator.concepts.general]中,我们有一个神奇的函数ITER_CONCEPT(I),它帮助我们确定在C++20中使用什么标记。

(2)的问题是,在添加新的contiguous_iterator_tag之前很难,因为各种C++98/17代码都会检查标记(很多代码可能会检查确切的random_access_iterator_tag)。iterator_concept方法通过引入直接为您检查正确事物的概念来避免这个问题(即,random_access_iterator概念检查ITER_CONCEPT(I)是从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_categoryiterator_concept类型别名。
票数 19
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67606563

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档