1

I have a question in iterators about the difference between begin() and rend().

#include <iostream>
#include <array>
#include <vector>
#include <algorithm>

using namespace std;

int main()
{
    vector<int> v1;
    v1 = {9,2,6,4,5};
    cout<<*v1.begin();
    cout<<*v1.rend();
    return 0;
}

cout<<*v1.begin(); returns 9

but cout<<*v1.rend(); returns a number that is not 9

Why are there such different results?

NAND
  • 663
  • 8
  • 22
Quốc Cường
  • 417
  • 4
  • 12
  • 1
    `rend().base() == begin()`. – Jarod42 Jun 15 '19 at 17:21
  • [`rend()`](https://en.cppreference.com/w/cpp/container/vector/rend) returns "past-the-end" iterator, just like `end()` does. Dereferencing it is Undefined Behaviour. (well, `rend()` is more of "before-the-begin", but you get the idea). – Yksisarvinen Jun 15 '19 at 17:21
  • `rend` is the reverse iterator the end (begin of original vector) and begin is the iterator to the begin – Oblivion Jun 15 '19 at 17:22
  • Here is a related question: [Why use rbegin() instead of end() - 1](https://stackoverflow.com/questions/32208657/why-use-rbegin-instead-of-end-1) – davidbak Jun 15 '19 at 17:26
  • `v1.begin() <=> --v1.rend()` – muaz Jun 15 '19 at 17:38
  • Does this answer your question? [What does"one-past-the-last-element" mean in vectors?](https://stackoverflow.com/questions/34830192/what-doesone-past-the-last-element-mean-in-vectors) – NAND Jul 11 '20 at 11:47

4 Answers4

10

In C++, ranges are marked by a pair of iterators marking the beginning of the range and a position one past the end of the range. For containers, the begin() and end() member functions provide you with a pair of iterators to the first and past-the-end positions. It’s not safe to read from end(), since it doesn’t point to an actual element.

Similarly, the rbegin() and rend() member functions return reverse iterators that point, respectively, to the last and just-before-the-first positions. For the same reason that it’s not safe to dereference the end() iterator (it’s past the end of the range), you shouldn’t dereference the rend() iterator, since it doesn’t point to an element within the container.

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
7

Dereferencing end() or rend() has undefined behaviour.

begin() points to the first element, rbegin() points to the last element. end() (in most cases) points to one after the last element and rend() effectively points to one before the first element (though it isn't implemented like that).

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Alan Birtles
  • 32,622
  • 4
  • 31
  • 60
  • It is "one past the end" so your loop can end on the condition `it == end()` (or `rend()` of course) and get every element in the range. (In a loop of course the end condition is the _negative_ of what you want so it is written `it != end()` but that's obvious.) – davidbak Jun 15 '19 at 17:23
  • _"though it isn't implemented like that"_ Why not? – Lightness Races in Orbit Jun 15 '19 at 18:19
  • @LightnessRacesinOrbit doesn't apply to all containers, but for example you cannot use pointer arithmetic to get address of the element before the first one of array like you can get the one past the last, can you? – eerorika Jun 15 '19 at 18:25
  • @eerorika Oh yeah :D – Lightness Races in Orbit Jun 15 '19 at 18:26
5

What is the difference between begin () and rend ()?

begin returns an iterator to the first element of the container.

rend returns a reverse iterator to one before the first element of the container (which is one past the last element in the reverse iterator range).

*v1.rend()

The behaviour of indirecting through the rend iterator is undefined (same goes for indirecting through end iterator).

Why are there such different results?

Besides behaviour being undefined in one case and not the other, since they refer to different to different elements (one of them being an element that doesn't exist), there is little reason to assume the results to be the same.

eerorika
  • 232,697
  • 12
  • 197
  • 326
3

vector::rend() is a built-in function in the C++ standard library which returns a reverse iterator pointing to the theoretical element right before the first element in the array container. but vector::begin() returns an iterator pointing to the first element in the vector.

See this code :

for (auto it = v1.rbegin(); it != v1.rend(); it++) 
    cout << *it << " ";

The vector elements in reverse order are :

5 4 6 2 9

To iterate in the vector always choose one of these methods together :

  • vector::begin() and vector::end()
  • vector::cbegin() and vector::cend()
  • vector::crbegin() and vector::crend()
  • vector::rbegin() and vector::rend()

For more information see "C++ Vector Tutorial With Example" by Ankit Lathiya.

Try it online

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055