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:

  1. You're calling std::begin(std::vector<int>&&), but std::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());
    

  1. 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).


  1. 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) calls v.begin(), which returns a const_iterator when called on const instances of std::vector.

Tags:

C++

C++11