![](/img/trans.png)
[英]What is a difference between iterator_category vs iterator_category() in std::iterator_traits
[英]What is the difference between iterator_category and iterator_concept in C++20?
C++20 带来了更强大的迭代器系统,其中之一就是在iterator_concept
的基础上引入了iterator_category
。
我发现C++20中很多迭代器的iterator_concept
和iterator_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_concept
和iterator_category
? iterator_category
在 C++20 中还有意义吗?
C++17 (C++98) 迭代器 model 和 C++20 Ranges 迭代器 model 之间存在不向后兼容的差异。 两个大的是:
value_type&
或value_type const&
的reference
。contiguous
迭代器。 最强的类别是random_access
。 (1) 的结果非常重要——这意味着如果您有一个返回纯右值的迭代器(无论是否代理引用),它永远不会比输入迭代器强。 因此, views::iota(1, 10)
尽管很容易支持随机访问,但充其量只是一个 C++98 输入范围。
但是,您不能只是...删除此要求。 假设 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
是纯右值,因此它不满足甚至向前的旧要求)但它的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
,而不仅仅是这样)。
指导方针:
std::iterator_traits<I>::iterator_category
。std::meow_iterator
概念iterator_category
别名并确保遵循前向迭代器/引用限制(或者......不要,但它在你身上)iterator_category
和iterator_concept
类型别名。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.