【问题标题】:Are the "defaults" for the type alises in std::iterator_traits always correct?std::iterator_traits 中的类型别名的“默认值”是否总是正确的?
【发布时间】:2021-05-29 00:32:24
【问题描述】:

我在cppreference 上读到过,在使用 C++20 时,可以在定义新迭代器时省略指定类型别名 referencepointeriterator_category。 在这种情况下,std::iterator_traits 中的相应别名将具有“默认”值。 这个细节对我来说有点confusing,所以我试图把这个话题分解成可以回答的问题。 所以,我的第一个问题是: 是否所有(或部分)这些“默认”别名都保证正确?

据我了解,iterator_category 标签基于 C++17 命名要求。 如果迭代器满足前向迭代器要求(但不满足双向要求),则其标记应为forward_iterator_tag

我特别担心forward_iterator_taginput_iterator_tag 之间的区别。 前向迭代器必须能够在多通道算法中使用,但我认为编译器不会检查这种情况。 在某些情况下我可以知道“默认”别名是正确的(例如,输出迭代器总是被正确分类,或者默认的 reference 别名总是正确的)?

【问题讨论】:

    标签: c++ iterator language-lawyer c++20


    【解决方案1】:

    定义“正确”。使用默认值的目的是充分覆盖最常见的情况,同时仍允许在需要时手动覆盖它们。这意味着,在这些情况下,默认值是不合适的。

    你能写一个默认值无效的类型吗?默认情况下,reference*t 返回的任何值,因此即使对于代理迭代器,默认值也很难出错。

    pointer 被定义为 operator-> 将产生的结果,但如果不存在这样的东西,它将是 void。但这没关系,因为 pointer trait 并没有真正有用,因为 operator-> 甚至要求任何迭代器类型都支持。

    iterator_category 的默认值更有可能产生不正确的结果,但这并不常见。输入迭代器不像其他类型那样常见,因此您可以通过在编写输入迭代器时指定标签来轻松避免问题。

    还应注意,iterator_category 指定符合 C++17 迭代器类别。通过提供iterator_concept 标记规范,可以覆盖 C++20 概念。

    另请注意,C++20 中的 ITER_CONCEPT 元函数提取 C++20 概念 explicitly bypasses the defaulting mechanism of iterator_category 的迭代器标记。也就是说,它只检查您在迭代器本身(通过iterator_conceptiterator_category 作为后备)或iterator_traits specialization 上明确指定的标签,而不是主要的默认标签iterator_traits 模板会产生。所以 C++20 的概念要求你以某种方式指定标签,尽管 iterator_traits::iterator_category 有一个默认机制。

    【讨论】:

    • 它仍然是可选的(这就是全大写 ITER_CONCEPT 魔术所做的)。不过,这里的设计从措辞上完全看不出来。
    • @T.C.:我没有注意到整个iterator_concept 是独立于iterator_category 的构造。现在一切都说得通了。
    • 当你说“如果不指定这个标签,一个迭代器就不能与任何 C++20 迭代器概念一致”,这是否意味着程序员必须指定 iterator_concept 标签才能符合有一个概念?因为我的印象是iterator_category就够了,可以省略。
    • @Irgendwhy:我弄错了我的目的。并不是必须指定iterator_concept 本身。这就是 ITER_CONCEPT 绕过默认的iterator_category。这意味着您需要以某种方式指定标签,iterator_concept 覆盖 iterator_category
    • 感谢您的回复,很抱歉再次打扰您,但我并没有真正关注。我对链接标准文本的阅读是,如果没有专业化,它会准确检查主模板,但默认不是专业化。我已经测试了在没有指定categoryconcept 的情况下定义输入迭代器(类似于我之前问题中的WeirdIterator 示例,但使用operator== 并且没有using iterator_category=...),以及gcc 和@987654354 @ 两人似乎都认为这是一个std::input_iterator
    猜你喜欢
    • 2021-05-28
    • 2020-09-03
    • 2020-05-08
    • 1970-01-01
    • 2016-05-02
    • 1970-01-01
    • 2021-12-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多