1

Take any STL container in mind which uses iterators.

The following is valid:

iterator begin();
const_iterator begin() const;
const_iterator cbegin() const;

Now I don't understand why the second line exists. Could someone provide a nice example where iterator begin(); wouldn't work and it can't be replaced by const_iterator cbegin();... begging the need for const_iterator begin();?

DeiDei
  • 10,205
  • 6
  • 55
  • 80

2 Answers2

2

There's probably no place in the language where you couldn't give something a different name; this is just a little act of kindness, a bit like size() and length() on std::string.

Remembering to use cbegin when working on a const container is a PITA, so the const_iterator begin() const is useful. At the same time, when I'm explicitly interested in obtaining a const iterator, without cbegin I'd have to do something convoluted like ((const std::vector<int> &)vec).begin(), which is certainly less readable/writable than vec.cbegin().

Now, you could argue that there are places where little acts of kindness like this are more sorely needed (and which scale better — supporting all the combinations of regular/reverse/const iterators quickly makes the interface explode), and I would certainly agree with you.

Incidentally, having the const_iterator begin avoids the need for other fiddling to make the range-based for loop work correctly on const objects.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
2

First off, there is a simple historic reason: the original C++ standard didn't use cbegin() and only had the two begin() overloads. It was felt that sometimes it would be useful to obtain const_iterators to a non-const sequence and cbegin() and cend() were added (despite begin() and end() members actually being ill-advise: we'd be much better of if they were just non-member functions). That is, if the const overload of begin() had been removed when cbegin() was introduced, at lot of code would have been broken.

From a practical point of view it is also desirable to have both the non-const and the const overloads:

  • use of begin() and cbegin() in normal code could be done it would be quite annoying to actually do so when changing the constness of objects
  • more importantly, in generic (templatized) code where sequence could be either const or non-const it would be necessary to use some dance to to use the correct overload.
Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380