4
it++;                       // OK    : Widely used expression for moving iterator.

it_prev = it-1;             // ERROR : What I expected; + - operators never existed
it_prev = std::prev(it)     // OK

it_next3 = it+3;            // ERROR : also, nothing like this exists
it_next3 = std::next(it,3)  // OK

Why does the Iterator class not have + - operators as member functions?

Or std::prev() as a member function to do this?

it_prev = it.prev()         // nothing like this

Is there a special reason for defining the prev function external to the iterator?

Boann
  • 48,794
  • 16
  • 117
  • 146
siamenock
  • 109
  • 1
  • 1
  • 9

2 Answers2

5

If prev() were a member function instead of a free function, it would be less generic since it won't be possible to work with built-in types (e.g., pointers) as iterators:

int *ptr = ...
// ...
ptr.prev() // <-- Pointers don't have member functions!!

whereas with a non-member function template, such as std::prev(), all is needed for it to work with pointers is a specialization that deals with pointers:

int *ptr = ...
// ...
std::prev(ptr); // <-- OK

Pointers also support the increment and decrement operators (i.e., ++ and --), so defining them in iterator classes doesn't hinder generic programming. The same reasoning applies to the binary operators + and -.

JFMR
  • 23,265
  • 4
  • 52
  • 76
2

Random access iterators do have operator+ overloaded. But others don't since something like it + n would have a linear complexity and most people don't expect that, especially considering iterators are also meant to be pointer-like for STL containers. That is also the reason why they don't have a member function called prev since pointers being valid iterator implementations is very convenient, efficient and desired. If you want to advance the iterator and don't mind the complexity, you can do that explicitly with std::advance:

std::advance

[...]

Increments given iterator it by n elements.

If n is negative, the iterator is decremented. In this case, InputIt must meet the requirements of LegacyBidirectionalIterator, otherwise the behavior is undefined.

[...]

Complexity

Linear.
However, if InputIt additionally meets the requirements of LegacyRandomAccessIterator, complexity is constant.

Community
  • 1
  • 1
Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93