【问题标题】:Why does the output_iterator Concept not require the output_iterator_tag?为什么 output_iterator 概念不需要 output_iterator_tag?
【发布时间】:2020-07-11 11:03:58
【问题描述】:

C++20 为标准库中不同类型的迭代器(输入、输出、前向、双向、随机访问等)引入了适当的概念。

虽然这些类型的原始命名要求根本没有提到 the iterator tags from 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>;

请注意最后一行中对迭代器标记的检查。所有迭代器概念都会检查相应的标签,except output iterator。 输出迭代器在这方面一直很特别,since the early days of the Ranges TS

与 C++ 标准中的输出迭代器要求不同, Ranges TS 中的 OutputIterator 不需要迭代器 定义类别标签。

对输出迭代器进行这种特殊处理的原因是什么?

【问题讨论】:

    标签: c++ c++20 c++-concepts


    【解决方案1】:

    在 C++20 中,迭代器类别通常根据语法自动检测。明确使用迭代器标签仅用于选择退出或选择加入:

    • random_access_iterator_tag 更弱的所有内容都用于选择退出更强的迭代器类别(例如,输入迭代器在语法上可能与前向迭代器无法区分);
    • contiguous_iterator_tag 用于选择加入 contiguous_iterator,因为连续性是一种相对罕见的属性,也无法从语法上检测到。

    输出迭代器不需要这种细粒度的控制——你可以或者你不能写入它,这在语法上是可以检测到的。


    至于何时提供选择加入/选择退出,Casey Carter explained

    • 将参数传递给约束该参数的库组件是该参数不满足的隐式声明 约束(不符合句法要求)或它 对约束建模(满足语法和语义 要求),因此通常不需要选择加入/退出。

    • 选择加入/退出工具仅在我们希望使库能够假设模型某个概念 X 的参数时提供 当满足 Y 时,另外对 X 的一些细化 Y 进行建模。(我已经 一直称之为“语义提升”,但它不是 完善的术语。)选择加入与退出的选择取决于 误报的预期频率。

    “语义提升”通常在非输出迭代器参数上完成。输出迭代器没有什么可提升的。

    【讨论】:

    • 我还不相信选择退出的说法。 Forward、Bidirectional 和 RandomAccess 都有不同的语法要求,使它们与众不同:Bidirectional 没有运算符 ++=,forward 没有 -- 运算符。如果它们可以通过语法区分,为什么我需要额外的机制?此外,即使在满足语法要求时有选择退出的原因,为什么这个原因现在也不适用于输出迭代器?
    • 在语法上也无法检测到” 实际上,C++20 的 contiguous_iterator 概念有一些你可以在语法上关闭的东西。具体来说,就是将迭代器转换为指针的函数(to_address我相信它被调用了)。
    • @ComicSansMS:“为什么这个原因现在不适用于输出迭代器”因为iteratoroutput_iterator 具有可检测的语法要求。因此,一个概念可以机械地检测一个并阻止另一个。 input_iteratorforward_iterator 之间不是这种情况;它们之间的区别是 all 语义(复制一个意味着什么等)。
    • @NicolBolas to_address 适用于任何具有 -&gt; 的内容,只要您可以为它形成一个 pointer_traits 专业化。
    猜你喜欢
    • 2021-11-12
    • 1970-01-01
    • 1970-01-01
    • 2016-08-01
    • 1970-01-01
    • 2012-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多