基于对<Iterator,Iterator>的范围

Mar*_*ito 6 c++ boost iterator for-loop

我对以下答案有疑问:

/sf/answers/1108020651/

如上所述,我们不能像BGL这样使用基于范围的BGL:

   for(auto e : boost::edges(g))
       // do something with e
Run Code Online (Sandbox Code Playgroud)

但是,这里指出,我们可以重载使用基于语义的范围所需的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;}
Run Code Online (Sandbox Code Playgroud)

但是,编译器仍抱怨:

错误:没有匹配函数来调用' 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*/;});
Run Code Online (Sandbox Code Playgroud)

更新:C++ 17现在应该允许以下内容:-)

auto [ebegin,eend] = boost::edges(_graph);
Run Code Online (Sandbox Code Playgroud)

seh*_*ehe 7

迭代器对不是设计范围!该想法被语言和图书馆规范明确拒绝.见例如

如果您"发现它很烦人"来编写tie()解决方法,请使用

for (auto& edge : make_iterator_range(boost::edges(_graph)))
    /*do something with edge*/;
Run Code Online (Sandbox Code Playgroud)

你可以用boost::make_iterator_range更短的别名,但我的编辑器¹建议make_iterator_range我输入时完成mir.这对我来说很快


¹当然,那个编辑是Vim


T.C*_*.C. 5

在基于范围的for循环,名称查找非会员begin()end()只使用ADL.它不执行普通的非限定查找.§6.5.4[stmt.ranged] /p1.3:

  • 如果_RangeT是一个类型时,不合格-ID小号beginend被查找类的范围_RangeT,就好像由类成员访问查找(3.4.5),并且如果任一个(或两者)找到至少一个声明,[... ]

  • 否则,开始-EXPR最终EXPRbegin(__range)end(__range)分别在那里beginend在相关联的命名空间(3.4.2)的查找.[ 注意:不执行普通的非限定查找(3.4.1).- 结束说明 ]

因此,找不到您的begin()end()重载.