为什么从C++11中删除了对范围访问
Why was pair range access removed from C++11?
我刚刚发现,在某一点上,C++11草案对std::pair
有std::begin
/std::end
重载,这允许将一对迭代器视为适合在基于范围的for循环中使用的范围(N3126,第20.3.5.5节),但这一点后来被删除了。
有人知道它为什么被移走吗?
我发现删除非常不幸,因为似乎没有其他方法可以将一对迭代器视为一个范围。事实上:
- 基于范围的for循环中开始/结束的查找规则表示,开始/结束在1)中作为范围对象的成员函数查找2)作为"关联命名空间"中的自由函数查找
std::pair
没有开始/结束成员函数std::pair<T, U>
的唯一关联命名空间通常是namespace std- 我们自己不允许为
std::pair
过载std::begin
/std::end
- 我们不能为
std::pair
专门化std::begin
/std::end
(因为专门化必须是部分的,而函数不允许这样做)
我还有别的失踪的原因吗?
我认为Alisdair Meredith在2009年发表的论文《配对不会形成好的范围》至少是答案的一部分。基本上,许多算法返回的迭代器对实际上不能保证是有效的范围。出于这个原因,他们似乎从for range循环中删除了对pair<iterator,iterator>
的支持。然而,拟议的解决方案尚未得到充分采纳。
如果您确信某些迭代器对确实表示有效范围,那么您可以将它们包装成一个自定义类型,该类型提供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
之类的东西手动确认这一点,这有点令人尴尬。
您可以使用boost::make_iterator_range
。它使用begin()
和end()
方法构造了一个迭代器范围。CCD_ 17可以接受迭代器的CCD_。
使用c++11优化对上述答案进行扩展:
#include <utility>
template<class Iter>
struct range_t : public std::pair<Iter, Iter> {
using pair_t = std::pair<Iter, Iter>;
range_t(pair_t&& src)
: std::pair<Iter, Iter>(std::forward<pair_t>(src))
{}
using std::pair<Iter, Iter>::first;
using std::pair<Iter, Iter>::second;
Iter begin() const { return first; }
Iter end() const { return second; }
};
template<class Iter>
range_t<Iter> range(std::pair<Iter, Iter> p) {
return range_t<Iter>(std::move(p));
}
template<class Iter>
range_t<Iter> range(Iter i1, Iter i2) {
return range_t<Iter>(std::make_pair(std::move(i1), std::move(i2)));
}
// TEST:
#include <iostream>
#include <set>
using namespace std;
int main() {
multiset<int> mySet { 6,4,5,5,5,3,3,67,8,89,7,5,45,4,3 };
cout << "similar elements: ";
for (const auto&i : range(mySet.lower_bound(5), mySet.upper_bound(10))) {
cout << i << ",";
}
cout << "n";
int count = 0, sum = 0;
for (const auto& i: range(mySet.equal_range(5)))
{
++count;
sum += i;
}
cout << "5 appears " << count << " timesn"
<< "the sum is " << sum << "n";
return 0;
}
相关文章:
- 尝试通过多个向量访问变量时,向量下标超出范围
- 如何访问超出其块范围的对象?
- 在函数内创建的对象的范围 - 如果在函数外部存储和访问引用,它们是否有效?
- 给定一个C++嵌套的私有结构类型,是否有从文件范围静态函数访问它的策略
- 如何在C++中访问有序映射中的键的范围/间隔?
- 访问提升:shared_ptr 主范围外崩溃,断言失败:px != 0.指针的正确用法是什么?
- 我无法访问变量的值,即使我通过范围传递了它
- 限制多模板参数朋友函数可访问的类实例的范围
- 访问基于范围的循环(如for_each)中的std::map迭代器
- 如何访问范围外的类?
- 无法从另一个函数访问文件范围变量的内容
- 我们如何准备小内存池,其中每个线程可以独立访问某些位置范围?
- 枚举范围无法通过 C++ 中的类中的结构访问
- x64 DLL 堆栈访问超出范围?
- 为什么这个循环变量在循环范围之外是可访问的
- C++数组超出范围访问以计算指针有效?
- 删除复制构造函数和运算符=类范围访问
- C++嵌套范围访问
- 从 Outsie it 范围 C++ 访问局部变量
- 为什么从C++11中删除了对范围访问