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 callingstd::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 lackscbegin/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
.