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

C++20带来了更强大的迭代器系统,其中之一就是iterator_conceptiterator_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>);

虽然是Rmodels random_access_range,但iterator_category它的迭代器的the只是一个input_iterator_tag,与iterator_concept.

为什么C++20引入iterator_concept?它的目的是什么?如果我实现我自己的迭代器,我该如何界定iterator_conceptiterator_category正确?是否iterator_category仍然在C ++ 20的意思?

回答

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

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

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

但是,您不能只是……取消此要求。假定 C++98 迭代器并用于iterator_category进行判断的现有代码完全在其权利范围内假定 ifiterator_category是,例如,bidirectional_iterator_tagreference是对 的某种左值引用value_type

什么iterator_concept作用是增加一个新的C ++ 20层,它允许一个迭代都通告其C ++17分之98类别和,清楚,通告其C ++ 20类。所以回到这个iota_view<int, int>例子,那个视图的迭代器已经iterator_category设置为input_iterator_tag(因为它reference是一个纯右值,所以它不满足甚至向前的旧要求)但它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类型别名进行了很好的描述。

以上是C++20中的iterator_category和iterator_concept有什么区别?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>