[英]Why does the output_iterator Concept not require the output_iterator_tag?
C++20 为标准库中不同类型的迭代器引入了正确的概念(输入、output、正向、双向、随机访问……)。
虽然这些类型的原始命名要求根本没有提到std::iterator_traits
中的迭代器标记,但新的 C++20 概念明确要求它们。 参见例如input_iterator
概念( [iterator.concept.input] ):
template<class I>
concept input_iterator =
input_or_output_iterator<I> &&
indirectly_readable<I> &&
requires { typename ITER_CONCEPT(I); } &&
derived_from<ITER_CONCEPT(I), input_iterator_tag>;
请注意最后一行中对迭代器标记的检查。 除了 output iterator 之外,所有迭代器概念都会像这样检查相应的标签。 Output 迭代器在这方面一直很特别, 因为 Ranges TS 的早期:
与 C++ 标准中的 output 迭代器要求不同, Ranges TS 中的 OutputIterator 不需要定义迭代器类别标签。
对 output 迭代器进行这种特殊处理的原因是什么?
在 C++20 中,迭代器类别通常根据语法自动检测。 明确使用迭代器标签仅用于选择退出或选择加入:
random_access_iterator_tag
更弱的所有内容都用于选择退出更强的迭代器类别(例如,输入迭代器在语法上可能与前向迭代器无法区分);contiguous_iterator_tag
用于选择加入contiguous_iterator
,因为连续性是一种相对罕见的属性,也无法在语法上检测到。Output 迭代器不需要这种细粒度的控制——你可以或者你不能写它,这在语法上是可以检测到的。
至于何时提供选择加入/选择退出,Casey Carter 解释说:
将参数传递给约束该参数的库组件是一个隐式声明,即参数不满足约束(不满足语法要求)或者它确实满足约束(满足语法和语义要求)所以通常不需要选择加入/退出。
仅当我们希望使库假设模型某个概念 X 的参数另外在满足 Y 时模型 X 的某些细化 Y 时,才提供选择加入/选择退出功能。(我一直称之为“语义提升”,但这不是一个成熟的术语。)选择加入还是选择退出取决于误报的预期频率。
“语义提升”通常在非输出迭代器 arguments 上完成。 Output 迭代器没有什么可以提升的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.