繁体   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