【问题标题】:What type of __iter_concept<_Iter>什么类型的 __iter_concept<_Iter>
【发布时间】:2021-09-03 21:14:04
【问题描述】:

我看了std::random_access_iterator 和其他迭代器概念
这就是 GCC 实现的样子

template<typename _Iter>
    concept random_access_iterator = bidirectional_iterator<_Iter>
      && derived_from<__detail::__iter_concept<_Iter>,
              random_access_iterator_tag>
      && totally_ordered<_Iter> && sized_sentinel_for<_Iter, _Iter>
      && requires(_Iter __i, const _Iter __j,
          const iter_difference_t<_Iter> __n)
      {
    { __i += __n } -> same_as<_Iter&>;
    { __j +  __n } -> same_as<_Iter>;
    { __n +  __j } -> same_as<_Iter>;
    { __i -= __n } -> same_as<_Iter&>;
    { __j -  __n } -> same_as<_Iter>;
    {  __j[__n]  } -> same_as<iter_reference_t<_Iter>>;
      };

__iter_concept&lt;_Iter&gt; 是怎么派生出来的from random_access_iterator_tag 的?

【问题讨论】:

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


    【解决方案1】:

    __iter_concept&lt;_Iter&gt; 是如何从random_access_iterator_tag 派生的?

    因为它是这样写的。 __iter_concept 不是一个概念;它是一个 type (或类型别名)。 C++20 指定了一组规则,用于从实现 C++20 concept-ified 迭代器类别的有效迭代器中确定迭代器类别(前向、随机访问、输入等)。这些规则的名称容易混淆地命名为“ITER_CONCEPT”。

    这里的“概念”一词表示它使用 C++20 概念规则进行此计算,而不是 C++17 预概念规则。

    __detail::__iter_concept&lt;T&gt; 是 GCC 标准库中实现 ITER_CONCEPT 的模板元编程类型。由此得名。它生成一个继承自 ITER_CONCEPT 定义的类型的类型,以便使用它的概念可以使用derived_from 来检测迭代器类型。

    【讨论】:

    • 我知道这不是一个概念。我想知道它是如何从 random_access_iterator_tag 派生的,如果迭代器本身没有显式继承自它
    • @dodickgod:这是模板元编程。它根据 ITER_CONCEPT 规则计算类型。
    • 好的,谢谢,我会尝试追踪获取类型的路径。据我了解,它只能是 contiguous_iterator_tag 或 random_access_iterator_tag。我想我理解 std::derived_from 在这种情况下的目的
    • @NicolBolas 作为一个附带问题,知道为什么它说:{ __j + __n } -&gt; same_as&lt;_Iter&gt;;?考虑到__jconst,不应该是{ __j + __n } -&gt; same_as&lt;const _Iter&gt;;
    • @Afshin:函数的返回值为const 无关紧要。
    【解决方案2】:

    ___Capital 开头的符号保留给您的c++ 编译器和std 库用于内部实现细节。 (标准禁止在其他任何地方使用此类符号,除非您的编译器明确允许)。

    因此,该模板是用于实现该概念的 C++ 标准要求的一些内部实现细节。

    __detail::__iter_concept<_Iter>
    

    这是标准库内部实现获取给定类型标签的方法。它可能在标准头文件中的其他地方定义为 C++ 代码。它是如何工作的,我会阅读源代码。或者更确切地说,我只是假设它会按照它所说的那样做。

    天真的方法就是使用 std iterator_traits

    【讨论】:

      猜你喜欢
      • 2021-06-16
      • 2019-08-10
      • 2018-05-23
      • 1970-01-01
      • 2016-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多