我刚刚发现,有一次,C++11 草案有 std::begin
/std::end
std::pair
的重载允许将一对迭代器视为适合在基于范围的 for 循环中使用的范围(N3126,第 20.3.5.5 节),但这已被删除。
有人知道它为什么被删除吗?
我发现删除非常不幸,因为似乎没有其他方法可以将一对迭代器视为一个范围。确实:
- 在基于范围的 for 循环中查找 begin/end 的规则表明 begin/end 在 1) 作为范围对象的成员函数 2) 作为“关联命名空间”中的自由函数进行查找
-
std::pair
没有开始/结束成员函数 std::pair<T, U>
的唯一关联命名空间一般是命名空间std- 我们不允许重载
std::begin
/std::end
对于std::pair
我们自己 - 我们无法特化
std::begin
/std::end
对于std::pair
(因为特化必须是部分的,而函数不允许这样做)
还有其他我想念的方法吗?
最佳答案
我认为 2009 年的论文 "Pairs do not make good ranges" Alisdair Meredith 的作品至少是部分答案。基本上,许多算法返回实际上不能保证是有效范围的迭代器对。他们似乎删除了对 pair<iterator,iterator>
的支持出于这个原因,来自 for-range 循环。但是,建议的解决方案尚未被完全采用。
如果您确定某对迭代器确实代表了一个有效范围,那么您可以将它们包装成提供 begin()/end() 成员函数的自定义类型:
template<class Iter>
struct iter_pair_range : std::pair<Iter,Iter> {
iter_pair_range(std::pair<Iter,Iter> const& x)
: std::pair<Iter,Iter>(x)
{}
Iter begin() const {return this->first;}
Iter end() const {return this->second;}
};
template<class Iter>
inline iter_pair_range<Iter> as_range(std::pair<Iter,Iter> const& x)
{ return iter_pair_range<Iter>(x); }
int main() {
multimap<int,int> mm;
...
for (auto& p : as_range(mm.equal_range(42))) {
...
}
}
(未经测试)
我同意这有点小问题。返回有效范围的函数(如 equal_range)应该使用适当的返回类型来说明。有点尴尬,我们必须通过 as_range
之类的方式手动确认这一点。以上。
关于c++ - 为什么从 C++11 中删除了对范围访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6167598/