c++ - 为什么从 C++11 中删除了对范围访问?

标签 c++ foreach c++11 range std-pair

我刚刚发现,有一次,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/

相关文章:

c++ - SDL 基准声音

c# - Linq ForEach 与 AddRange 和包含并选择

c++ - Gtk::Notebook 不显示

随机数生成器的 C++11 线程安全

c++ - 当它们应用于构造函数时,括号初始值设定项列表中是否有序列点?

c++ - 如何使用 visual Studio 2010 编译和构建 librsync?

c++ - 使用 stringstream 将动态大小的字符串转换为整数

c# - 使用 LINQ 获取列表中的项目

c++ - 将一对成员分配给变量

arrays - 如何将数组呈现为单选按钮列表?