繁体   English   中英

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

[英]What is the difference between iterator_category and iterator_concept in C++20?

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

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

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_category iterator_category在 C++20 中还有意义吗?

C++17 (C++98) 迭代器 model 和 C++20 Ranges 迭代器 model 之间存在不向后兼容的差异。 两个大的是:

  1. C++98 model 要求正向迭代器具有value_type&value_type const&reference
  2. C++98 model 不允许contiguous迭代器。 最强的类别是random_access

(1) 的结果非常重要——这意味着如果您有一个返回纯右值的迭代器(无论是否代理引用),它永远不会比输入迭代器强。 因此, 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是纯右值,因此它不满足甚至向前的旧要求)但它的iterator_concept设置为random_access_iterator_tag (因为一旦我们放弃该限制,我们就可以轻松支持所有随机访问限制)。

[iterator.concepts.general]中,我们有这个神奇的 function 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 ,而不仅仅是这样)。


指导方针:

  • 如果您在 C++17 中使用迭代器,请使用std::iterator_traits<I>::iterator_category
  • 如果您在 C++20 中使用迭代器,请使用std::meow_iterator概念
  • 如果您在 C++17 中编写迭代器,请添加iterator_category别名并确保遵循前向迭代器/引用限制(或者......不要,但它在你身上)
  • 如果您使用 C++20编写迭代器,请遵循P2259中的指导,该指导很好地描述了问题以及如何以及何时提供iterator_categoryiterator_concept类型别名。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM