简体   繁体   中英

Why are std::begin() and std::end() overloaded for std::initializer_list in C++11?

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 and end functions in namespace std ) 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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM