[英]Why are std::begin() and std::end() overloaded for std::initializer_list in C++11?
在C ++ 11(引用N3337)中, std::begin()
和std::end()
被指定為(§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返回:
c.begin()
。template <class C> auto end(C& c) -> decltype(c.end()); template <class C> auto end(const C& c) -> decltype(c.end());
3返回:
c.end()
。
但是, std::initializer_list
為這些函數提供了自己的重載(第18.9.3節[support.initlist.range]):
template<class E> const E* begin(initializer_list<E> il) noexcept;
1返回:
il.begin()
。template<class E> const E* end(initializer_list<E> il) noexcept;
2返回:
il.end()
。
似乎這些重載除了基本模板之外沒有做任何事情,除了(1)具有noexcept
規范和(2)按值獲取它們的參數。 但是,復制initializer_list
沒有什么特別之處(它只是復制一對指針或同樣輕量級的東西),因此(2)沒有產生任何行為上的差異。 此外,許多標准容器的begin()
和end()
成員函數也是noexcept
,但沒有為這些容器指定std::begin()
/ std::end()
重載,因此委員會似乎不太可能指定這些重載僅適用於(1)。 那么,為什么要提供這些重載?
這在N2930中進行了解釋, N2930提出了更改以添加有問題的重載。 我的重點:
建議修改摘要
- 在不使用概念的情況下指定基於范圍的語句,使用begin和end的參數依賴查找(它總是包括命名空間
std
begin
和end
函數),以提供序列開頭和結尾的迭代器。- 指定基於范圍的語句, 以便數組和初始化程序列表不依賴於
<iterator>
。- 重構
<initializer_list>
,使其不依賴於其他標頭,並且不包含其他標頭。- 指定要
#include <initializer_list>
的庫頭。
似乎他們沒有解釋為什么他們希望<initializer_list>
不依賴於<iterator>
,但我認為合理的猜測是前者應該在獨立實現中可用,而后者可能不是(表16,§17.6.1.3)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.