【问题标题】:No type named 'iterator_category' in 'struct std::iterator_traits<int* const>'“struct std::iterator_traits<int* const>”中没有名为“iterator_category”的类型
【发布时间】:2021-12-31 13:30:33
【问题描述】:

我正在编写一个自定义矢量类:

#include <iterator>

template <typename T>
class vector {
 public:
  using value_type = T;
  using pointer = value_type*;
  using iterator = pointer;
  using const_iterator = const iterator;
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;

  auto crbegin() const -> const_reverse_iterator {
    return const_reverse_iterator(data_);
  }

 private:
  pointer data_{};
};

int main(int argc, char* argv[]) {
  vector<int> v;
  auto i = v.crbegin();

  return 0;
}

在编译上面的代码时,我得到了这个错误(在 GCC 和 MSVC 上):

error: no type named ‘iterator_category’ in ‘struct std::iterator_traits<int* const>’

当我将反向迭代器定义更改为 std::reverse_iterator&lt;const T*&gt; 时,错误消失了。和std::reverse_iterator&lt;const_iterator&gt;相比有什么区别?

【问题讨论】:

    标签: c++ iterator c++20 iterator-traits


    【解决方案1】:

    问题可以简化为:

    #include <iterator>
    
    template <typename T>
    class vector {
     public:
      using value_type = T;
      using pointer = value_type*;
      using const_reverse_iterator = std::reverse_iterator<const pointer>;
    
      auto crbegin() const -> const_reverse_iterator {
        return const_reverse_iterator(data_);
      }
    
     private:
      pointer data_{};
    };
    
    int main() {
      vector<int> v;
      auto i = v.crbegin();
      (void) i;
      return 0;
    }
    

    而来自 clang 的错误信息让问题的本质更加清晰:

    no type named 'reference' in 'std::iterator_traits&lt;int *const&gt;'
    ^^^^^^^^^^

    因此我们看到您认为是const *int(即指向的对象是const)实际上是int *const(即指针本身是const)。

    这里有一个简单的解决方法:

    #include <iterator>
    
    template <typename T>
    class vector {
     public:
      using value_type = T;
      using pointer = value_type*;
      using const_pointer = const value_type*;
      using const_reverse_iterator = std::reverse_iterator<const_pointer>;
    
      auto crbegin() const -> const_reverse_iterator {
        return const_reverse_iterator(data_);
      }
    
     private:
      pointer data_{};
    };
    
    int main() {
      vector<int> v;
      auto i = v.crbegin();
      (void) i;
      return 0;
    }
    

    Live demo

    【讨论】:

    • 谢谢。你知道为什么const pointer 会评估为int* const 而不是const int* 的顺序建议吗?
    • 不确定,抱歉,我不是语言律师。您可以发布一个单独的问题,仅关注该问题并适当地标记它。
    • @jsmolka 这就是为什么人们建议使用“east const”风格写作的原因,所以你不要提出这个问题。 pointer constint* const - 这是 pointerconst,没有任何内容。使用“west const”,它看起来就像const pointer 给了你const int*(就像简单的测试替换一样)但是你正在应用顶级 const,而不是内部const .
    猜你喜欢
    • 1970-01-01
    • 2020-05-08
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 2013-04-14
    • 2016-07-14
    • 2021-05-28
    相关资源
    最近更新 更多