Why does std::cbegin() not call .cbegin() on the container?

this fails because std::cbegin() calls the .begin()

To be more precise, std::cbegin calls std::begin, which in the generic overload calls c.begin.

For what it's worth, it should be possible to fix gsl::span to return const iterator upon std::cbegin if the designers of gsl specify that there is a specialisation for the generic overload of std::cbegin for gsl::span that uses c.cbegin instead of std::begin, if that is the desired behaviour. I don't know their reasoning for not specifying such specialisation.

As for reasoning for why std::cbegin uses std::begin, I do not know for fact either, but it does have the advantage of being able to support containers that have a c.begin member, but not a c.cbegin member, which can be seen as a less strict requirement, as it can be satisfied by custom containers written prior to C++11, when there was no convention of providing a c.cbegin member function.


First, note that, per [tab:container.req]:

Expression: a.cbegin()

Return type: const_­iterator

Operational semantics: const_­cast<​X const&​>(a)​.begin();

Complexity: constant

Therefore, gsl::span is not a container at all. cbegin and cend are designed to work with containers. There are some exceptions (arrays, initializer_list) that require special care, but apparently the standard library cannot mention something like gsl::span.

Second, it is LWG 2128 that introduced global cbegin and cend. Let's see what the relevant part says:

Implement std::cbegin/cend() by calling std::begin/end(). This has numerous advantages:

  • It automatically works with arrays, which is the whole point of these non-member functions.

  • It works with C++98/03-era user containers, written before cbegin/cend() members were invented.

  • It works with initializer_list, which is extremely minimal and lacks cbegin/cend() members.

  • [container.requirements.general] guarantees that this is equivalent to calling cbegin/cend() members.

Essentially, calling std::begin/end() save the work of providing special care for arrays and initializer_list.

Tags:

C++