In C++11 (quoting N3337), std::begin()
and std::end()
are specified as (§24.7 [iterator.range]/p2-3)
template <class C> auto begin(C& c) -> decltype(c.begin()); template <class C> auto begin(const C& c) -> decltype(c.begin());
2 Returns:
c.begin()
.template <class C> auto end(C& c) -> decltype(c.end()); template <class C> auto end(const C& c) -> decltype(c.end());
3 Returns:
c.end()
.
std::initializer_list
, however, provides its own overloads for these functions (§18.9.3 [support.initlist.range]):
template<class E> const E* begin(initializer_list<E> il) noexcept;
1 Returns:
il.begin()
.template<class E> const E* end(initializer_list<E> il) noexcept;
2 Returns:
il.end()
.
It seems that these overloads don't do anything beyond the base template, other than (1) having a noexcept
specification and (2) taking their parameter by value. However, copying an initializer_list
does nothing special (it just copies a pair of pointers or something equally lightweight), so (2) creates no difference in behavior. Moreover, the begin()
and end()
member functions of many standard containers are also noexcept
, yet no overloads of std::begin()
/std::end()
are specified for those containers, so it seems unlikely the committee specified these overloads just for (1). Why, then, are these overloads provided?
This is explained in N2930, which proposed the change to add the overloads in question. Emphasis mine:
Summary of proposed changes
- Specify range-based for statements without the use of concepts, using argument-dependent lookup of begin and end (which always includes those
begin
andend
functions in namespacestd
) to provide the iterator to the beginning and ending of the sequence.- Specify range-based for statements so that arrays and initializer lists have no dependencies on
<iterator>
.- Refactor
<initializer_list>
so that it as no dependencies on other headers and includes no other headers.- Specify the library headers that are to
#include <initializer_list>
.
It seems like they didn't explain why they wanted <initializer_list>
to have no dependency on <iterator>
, but I think a reasonable guess is that the former is supposed to be available in a freestanding implementation whereas the latter might not be (Table 16, §17.6.1.3)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With