为什么从 C++11 中删除了对范围访问?
我刚刚发现,在某一时刻,C++11 草案对 std::pair
有 std::begin
/std::end
重载> 允许将一对迭代器视为适合在基于范围的 for 循环中使用的范围(N3126,第 20.3.5.5 节),但这已被删除。
有谁知道为什么被删除?
我发现删除非常不幸,因为似乎没有其他方法可以将一对迭代器视为一个范围。事实上:
- 基于范围的 for 循环中开始/结束的查找规则表示,开始/结束在 1) 作为范围对象的成员函数 2) 作为“关联命名空间”
std:: 中的自由函数进行查找pair
没有 begin/end 成员函数std::pair
唯一关联的命名空间一般是命名空间 std- 我们不允许重载
std::begin
/std::end
对于std::pair
我们自己 - 我们不能专门化
std::begin
/std::end
forstd::pair
(因为专业化必须是部分的,并且函数不允许)
是否有其他我缺少的方法?
I just discovered that at one point, the C++11 draft had std::begin
/std::end
overloads for std::pair
that allowed treating a pair of iterators as a range suitable for use in a range-based for loop (N3126, section 20.3.5.5), but this has since been removed.
Does anyone know why it was removed?
I find the removal very unfortunate, because it seems there is no other way to treat a pair of iterators as a range. Indeed:
- The lookup rules for begin/end in a range-based for loop say that begin/end are looked for in 1) as member functions of the range object 2) as free functions in "associated namespaces"
std::pair
does not have begin/end member functions- The only associated namespace for
std::pair<T, U>
in general is namespace std - We are not allowed to overload
std::begin
/std::end
forstd::pair
ourselves - We cannot specialize
std::begin
/std::end
forstd::pair
(because the specialization would have to be partial and that's not allowed for functions)
Is there some other way that I am missing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我认为 2009 年的论文 " 配对效果不佳Alisdair Meredith 的“范围”至少是答案的一部分。基本上,许多算法返回的迭代器对实际上不能保证是有效范围。出于这个原因,他们似乎从 for-range 循环中删除了对pair的支持。然而,所提出的解决方案尚未被完全采纳。
如果您确定某对迭代器确实代表有效范围,那么您可以将它们包装到提供 begin()/end() 成员函数的自定义类型中:(
未经测试)
我同意这是有点疣。返回有效范围(如 equal_range)的函数应该使用适当的返回类型来说明。有点尴尬的是,我们必须通过上面的
as_range
之类的东西来手动确认这一点。I think the 2009 paper "Pairs do not make good ranges" by Alisdair Meredith is at least part of the answer. Basically, many algorithms return pairs of iterators that are actually not guaranteed to be valid ranges. It seems they removed the support for
pair<iterator,iterator>
from the for-range loop for this reason. However, the proposed solution has not been fully adopted.If you know for certain that some pair of iterators really represents a valid range then you could wrap them into a custom type which offers begin()/end() member functions:
(untested)
I agree this is a bit of a wart. Functions which return valid ranges (like equal_range) should say so using an appropriate return type. It's a bit embarrasing that we have to manually confirm this via something like
as_range
above.您可以使用boost::make_iterator_range。
它使用
begin()
和end()
方法构造一个 iterator_range。boost::make_iterator_range
可以接受std::pair
迭代器。You can use
boost::make_iterator_range
.It constructs an iterator_range with
begin()
andend()
methods.boost::make_iterator_range
can acceptstd::pair
of iterators.使用 c++11 优化扩展上述答案:
expanding on the above answer using c++11 optimisations: