繁体   English   中英

基于对的范围<Iterator,Iterator>

[英]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 s beginend ,就像通过类成员访问查找(3.4.5)一样,并且如果其中任何一个(或两者)找到至少一个声明, [...]

  • 否则, begin-exprend-expr分别是begin(__range)end(__range) ,其中beginend在相关的命名空间中查找(3.4.2)。 [ 注意 :不执行普通的非限定查找(3.4.1)。 - 结束说明 ]

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

根据TC的回答,您不能拥有免费的begin()end()函数。 但是,您可以做的只是创建自己的类并添加成员的beginend

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可用。

另一种方法是创建自己的类,该类派生自该对,但包含beginend成员。 然后写

for (e: mypair(p))

代替

for (e: p)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM