问题
cppreference shows this signature for std::cbegin:
template< class C >
constexpr auto cbegin( const C& c ) -> decltype(std::begin(c));
Shouldn't it return something like C::const_iterator instead?
回答1:
c is a const reference, so std::begin(c) it will return whatever the const overload of C::begin() returns. For standard library types, this is a const_iterator. For an array type, it is a pointer to const.
Note that this relies on other, non-standard library user defined C, being implemented sanely with a const overload for C::begin() that returns an iterator that gives you const access to the container's elements.
回答2:
std::begin returns an iterator or a const_iterator, depending on the whether the argument is const or not, see e.g. http://en.cppreference.com/w/cpp/iterator/begin and the declaration of a member function begin for a 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 turns returns a const_iterator.
回答3:
cbegin is implemented like below :
template <class C>
auto cbegin(const C& container)->decltype(std::begin(container))
{
return std::begin(container); // see explanation below
}
corresponding begin is as below .
template< class C >
auto begin( C& c ) -> decltype(c.begin()); //calling container's begin
This cbegin template accepts any type of argument representing a container-like data structure, C, and it accesses this argument through its reference-to-const parameter, container. If C is a conventional container type (e.g., a std::vector), container will be a reference to a const version of that container (e.g., a const std::vector&). Invoking the nonmember begin function (provided by C++11) on a const container yields a const_iterator, and that iterator is what this template returns.
For example , if I have used vector as an argument to cbegin like below .
std::vector<int> v1;
std::cbegin(v1);
Now , see how template deduction happened in this case , template(class C) is deduced to be vector and parameter of cbegin (const C& container) deduced to be const vector<int> & . Now since container is itself is constant , it will return constant version of begin of vector .
iterator begin();
const_iterator begin() const; //This will be used .
const_iterator cbegin() const;
来源:https://stackoverflow.com/questions/29486309/why-does-stdcbegin-return-the-same-type-as-stdbegin