Is it specified in the C++11 standard that std::begin(Container&&) returns const_iterator?
As you can see in http://en.cppreference.com/w/cpp/iterator/begin the interesting overloads are:
template<class C> auto begin(C& c) -> decltype(c.begin());
template<class C> auto begin(const C& c) -> decltype(c.begin());
and std::vector<int>&&
can only bind to the second overload (so returns const_iterator
).
Let's try to analyze what happens, step by step:
You're calling
std::begin(std::vector<int>&&)
, butstd::begin
has no overload that takes an rvalue:template< class C > auto begin( C& c ) -> decltype(c.begin()); template< class C > auto begin( const C& c ) -> decltype(c.begin());
Due to reference collapsing, a temporary (xvalue) will only bind to a
const
lvalue reference:If you call Fwd with an xvalue, we again get Type&& as the type of v. This will not allow you to call a function that takes a non-const lvalue, as an xvalue cannot bind to a non-const lvalue reference. It can bind to a const lvalue reference, so if Call used a const&, we could call Fwd with an xvalue.
(From the linked answer).
Therefore, the
template<class C> auto begin(const C& c) -> decltype(c.begin());
overload is being called, which returns a
const
iterator.Why?
Because
std::begin(v)
callsv.begin()
, which returns aconst_iterator
when called onconst
instances ofstd::vector
.