Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

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>?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

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 (i.e. the pointed-to object is const) is in fact a, int *const (i.e 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

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading