簡體   English   中英

為什么在C ++ 11中為std :: initializer_list重載了std :: begin()和std :: end()?

[英]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 beginend函數),以提供序列開頭和結尾的迭代器。
  • 指定基於范圍的語句, 以便數組和初始化程序列表不依賴於<iterator>
  • 重構<initializer_list> ,使其不依賴於其他標頭,並且不包含其他標頭。
  • 指定要#include <initializer_list>的庫頭。

似乎他們沒有解釋為什么他們希望<initializer_list>不依賴於<iterator> ,但我認為合理的猜測是前者應該在獨立實現中可用,而后者可能不是(表16,§17.6.1.3)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM