I wonder why cbegin
and cend
were introduced in C++11?
What are cases when calling these methods makes a difference from const overloads of begin
and end
?
I wonder why cbegin
and cend
were introduced in C++11?
What are cases when calling these methods makes a difference from const overloads of begin
and end
?
Take this as a practical usecase
The assignment fails because
it
is a nonconst iterator. If you used cbegin initially, the iterator would have had the right type.Beyond what Nicol Bolas said in his answer, consider the new
auto
keyword:With
auto
, there's no way to make sure thatbegin()
returns a constant operator for a non-constant container reference. So now you do:From http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1674.pdf:
They gave this example
Note that the working paper also mentions adapter templates, that now have been finalized as
std::begin()
andstd::end()
and that also work with native arrays. The correspondingstd::cbegin()
andstd::cend()
are curiously missing as of this time, but they might also be added.It's quite simple. Say I have a vector:
I fill it with some data. Then I want to get some iterators to it. Maybe pass them around. Maybe to
std::for_each
:In C++03,
SomeFunctor
was free to be able to modify the parameter it gets. Sure,SomeFunctor
could take its parameter by value or byconst&
, but there's no way to ensure that it does. Not without doing something silly like this:Now, we introduce
cbegin/cend
:Now, we have syntactic assurances that
SomeFunctor
cannot modify the elements of the vector (without a const-cast, of course). We explicitly getconst_iterator
s, and thereforeSomeFunctor::operator()
will be called withconst int &
. If it takes it's parameters asint &
, C++ will issue a compiler error.C++17 has a more elegant solution to this problem:
std::as_const
. Well, at least it's elegant when using range-basedfor
:This simply returns a
const&
to the object it is provided.Just stumbled upon this question... I know it's alredy answerd and it's just a side node...
auto const it = container.begin()
is a different type thenauto it = container.cbegin()
the difference for
int[5]
(using pointer, which i know don't have the begin method but show nicely the difference... but would work in c++14 forstd::cbegin()
andstd::cend()
, which is essentially what one should use when it's here)...iterator
andconst_iterator
have inheritance relationship and an implicit conversion occurs when compared with or assigned to the other type.Using
cbegin()
andcend()
will increase performance in this case.