[英]Range based for with pair<Iterator,Iterator>
我对以下答案有疑问:
https://stackoverflow.com/a/15828866/2160256
如上所述,我们不能像BGL这样使用基于范围的BGL:
for(auto e : boost::edges(g))
// do something with e
但是, 这里指出,我们可以重载使用基于语义的范围所需的begin()和end()函数。 所以我尝试过:
template<class I>
I begin(std::pair<I,I>& p)
{ return p.first;}
template<class I>
I end(std::pair<I,I>& p)
{ return p.second;}
但是,编译器仍抱怨:
错误:没有用于调用'
begin(std::pair<some_really_ugly_type,some_really_ugly_type>&)
的匹配函数
我究竟做错了什么? 名称查找不起作用吗? 或者这毕竟不可能吗? 我也找到了这个答案 , 这个答案是有效的,但是开头/结尾自由函数的过度也不应该是可能的吗? 问候,马蒂
顺便说一句:我觉得写作真的很烦人
typename Graph::edge_iterator ebegin, eend;
std::tie(ebegin,eend) = boost::edges(_graph);
std::for_each(ebegin,eend,[&](const edge_descriptor& e){/*do something with e*/;});
更新:C ++ 17现在应该允许以下内容:-)
auto [ebegin,eend] = boost::edges(_graph);
迭代器对不是设计范围! 该想法被语言和图书馆规范明确拒绝。 见例如
如果您“发现它很烦人”来编写tie()
解决方法,请使用
for (auto& edge : make_iterator_range(boost::edges(_graph)))
/*do something with edge*/;
你可以将boost::make_iterator_range
别名更短,但是当我输入mir
时,我的编辑器¹建议make_iterator_range
为完成。 这对我来说很快
¹当然,那个编辑是Vim
在基于范围的for
循环中,非成员begin()
和end()
名称查找仅使用ADL。 它不执行普通的非限定查找。 §6.5.4[stmt.ranged] /p1.3:
如果
_RangeT
是一个类类型,则在类_RangeT
的范围内查找unqualified-id sbegin
和end
,就像通过类成员访问查找(3.4.5)一样,并且如果其中任何一个(或两者)找到至少一个声明, [...]否则, begin-expr和end-expr分别是
begin(__range)
和end(__range)
,其中begin
和end
在相关的命名空间中查找(3.4.2)。 [ 注意 :不执行普通的非限定查找(3.4.1)。 - 结束说明 ]
因此,找不到您的begin()
和end()
重载。
根据TC的回答,您不能拥有免费的begin()
和end()
函数。 但是,您可以做的只是创建自己的类并添加成员的begin
和end
:
template <typename I>
struct iter_pair : std::pair<I, I>
{
using std::pair<I, I>::pair;
I begin() { return this->first; }
I end() { return this->second; }
};
而只是使用它而不是正常的pair
:
std::vector<int> v = {1, 2, 3, 4, 5};
iter_pair<decltype(v.begin())> pr{v.begin(), v.end()};
for (int i : pr) {
std::cout << i << ' ';
}
std::cout << std::endl;
我将扩展Barry的答案并建议(直到C ++ 17)添加
template <typename I>
iter_pair<I> make_range(std::pair<I, I> p) {
return iter_pair<I>(p);
}
用作
for (auto e : make_range(boost::edges(g)))
// do something with e
由于Boost FOREACH宏使用C ++ 03声明和显式模板代码,因此它应该使用传统的查找规则而不是特殊for
规则。
其膨胀,即使范围为基础的旧的方式也可以确保for
可用。
另一种方法是创建自己的类,该类派生自该对,但包含begin
和end
成员。 然后写
for (e: mypair(p))
代替
for (e: p)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.