Why std :: cbegin returns the same type as std :: begin

cppreference shows this signature for std::cbegin :

 template< class C > constexpr auto cbegin( const C& c ) -> decltype(std::begin(c)); 

Shouldn't something like C::const_iterator be returned instead?

+7
c ++ iterator c ++ 14
source share
3 answers

c is a const reference, so std::begin(c) returns everything that const overloads C::begin() returns. For standard library types, this is const_iterator . For an array type, this is a pointer to const .

Note that this depends on another non-standard library defined by user c , which is implemented with a const overload for C::begin() , which returns an iterator that gives you const access to the elements of the container.

+12
source share

std::begin returns an iterator or const_iterator , depending on whether the argument is const or not, see for example http://en.cppreference.com/w/cpp/iterator/begin and the declaration of the begin member function for standard container http://en.cppreference.com/w/cpp/container/vector/begin

std::cbegin returns what std::begin returns (via decltype ), so if you have a const object, the const overload is selected, which in turn returns const_iterator .

+3
source share

cbegin is implemented as shown below:

 template <class C> auto cbegin(const C& container)->decltype(std::begin(container)) { return std::begin(container); // see explanation below } 

the beginning begins as shown below.

 template< class C > auto begin( C& c ) -> decltype(c.begin()); //calling container begin 

This cbegin template accepts any type of argument representing a data structure similar to a container, C, and it accesses this argument through its reference-to-const, container parameter. If C is a regular type container (for example, a std :: vector), the container will be a reference to the version constant of that container (for example, const std :: vector &). Calling the begin member (provided by C ++ 11) in the const container gives a const_iterator, and this iterator returns this template.

For example, if I used the vector as an argument to cbegin , as shown below.

 std::vector<int> v1; std::cbegin(v1); 

Now, let's see how the template was divided in this case, the template (class C) is displayed as a vector and the cbegin parameter (const C & container), which is calculated as const vector<int> & . Now, since the container itself is constant, it will return a constant version of the beginning of the vector.

 iterator begin(); const_iterator begin() const; //This will be used . const_iterator cbegin() const; 
+2
source share

All Articles