简体   繁体   中英

No type named 'iterator_category' in 'struct std::iterator_traits<int* const>'

I'm writing a custom vector class:

#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;
}

When compiling the code above, I get this error (on GCC and MSVC):

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

The error goes away when I change the reverse iterator definition to std::reverse_iterator<const T*> . What's the difference compared to std::reverse_iterator<const_iterator> ?

The problem can be reduced to this:

#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;
}

And the error message from clang makes the nature of the problem clearer:

no type named 'reference' in 'std::iterator_traits<int *const>'
^^^^^^^^^^

And so we see that what you thought was a const *int (ie the pointed-to object is const ) is in fact a, int *const (ie the pointer itself is const ).

Here's a fix:

#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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM