13

Beginning with C++17 inheriting from std::iterator<...> is deprecated. Instead one should specialize the std::iterator_traits<...> for the own iterator type.

I used to write my iterator class as nested types in the container classes they belong to.

Trying to partial specialize the std::iterator_traits<C<T>> leads to a non-deducible context for the value type T for my container C.

The question: should I now (as of C++17) define my iterator classes outside my container classes?

T.C.
  • 133,968
  • 17
  • 288
  • 421
wimalopaan
  • 4,838
  • 1
  • 21
  • 39
  • 1
    "Instead one should specialize the `std::iterator_traits<...>` for the own iterator type." Where did you hear this from? – T.C. Aug 21 '17 at 07:47
  • If it is deprecated to derived from `std::interator<...>` my thought was, I had to specialize `std::iterator_traits` – wimalopaan Aug 21 '17 at 07:55
  • Well, I also read this in the "C++17 STL Cookbook" by Jacek Galowicz. – wimalopaan Aug 21 '17 at 07:56
  • 2
    Specializing `std::iterator_traits` might be useful for some functions that needs it, but it's not necessary. On the other hand, inheriting from `std::iterator` wasn't necessary either. – Some programmer dude Aug 21 '17 at 07:58
  • As per the book "Until C++17, it was encouraged to let iterator types just inherit from std::iterator<...>, which automatically populates our class with all the type definitions. This still works, but it is discouraged since C++17" so its not deprecated – Hariom Singh Aug 21 '17 at 08:00
  • @HariomSingh `std::iterator` *is* deprecated in C++17. That is why its use is discouraged. – eerorika Aug 21 '17 at 08:01
  • Please look at http://en.cppreference.com/w/cpp/iterator/iterator, the template `std::iterator` is deprecated. – wimalopaan Aug 21 '17 at 08:01
  • And algorithms like `std::copy` clearly need a specialization of `std::iterator_traits<>`. – wimalopaan Aug 21 '17 at 08:02
  • @wimalopaan the non-specialized `std::iterator_traits` is fine for most custom iterators. You don't need to specialize unless your iterator is special. – eerorika Aug 21 '17 at 08:04
  • 2
    Why would they need a specialization of `iterator_traits`? The only thing `iterator_traits` does is exposing iterator own type aliases. If your iterator is implemented properly, the defaut version would work just fine. – Revolver_Ocelot Aug 21 '17 at 08:05
  • The usual solution is to provide the appropriate typedefs in the iterator itself. That "cookbook" sounds like complete nonsense. – T.C. Aug 21 '17 at 08:06
  • Well, I did that for the five, but I still get the errors from `std::copy` needing the the `std::iterator_traits` specialization ... don't know whats going on here. I'm using `g++-7.1` with `-std=c++17` – wimalopaan Aug 21 '17 at 08:11
  • Are your typedefs public? – T.C. Aug 21 '17 at 08:12
  • Yes: public typedefs for at least `value_type` and `iterator_category` in the nested, public custom iterator class. – wimalopaan Aug 21 '17 at 08:14
  • 1
    You need all five. – T.C. Aug 21 '17 at 08:19
  • Ok, very misleading error, since that only complains about `value_type` and `iterator_category`. I was missing `difference_type` since its not needed for my case, and I thought it would be best in this case not to define the typedef for it. Now I defined it to `void` and its ok. Thanks very much! – wimalopaan Aug 21 '17 at 08:25
  • @Holt You *do* need all five. Miss one and `iterator_traits` won't give you any. – T.C. Aug 21 '17 at 16:59
  • @T.C. You're right, I misunderstood the quote from cppreference. – Holt Aug 21 '17 at 17:04

0 Answers0