我对以下答案有疑问:
https://stackoverflow.com/a/15828866/2160256
如上所述,我们不能像BGL一样使用基于范围的:
for(auto e : boost::edges(g))
// do something with e
然而,here它指出,我们可以重载使用基于语义的范围所需的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>&)
”
我做错了什么?名称查找不起作用吗?或者这毕竟不可能吗? 我还发现了this answer,它有效,但是不应该使用开始/结束自由函数overlods吗? 此致,Marti
顺便说一句:我觉得写作真的很烦人
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);
答案 0 :(得分:6)
迭代器对不范围的设计!该想法被语言和图书馆规范明确拒绝。参见例如
如果您“发现它很烦人”来编写tie()
解决方法,请使用
for (auto& edge : make_iterator_range(boost::edges(_graph)))
/*do something with edge*/;
您可以将boost::make_iterator_range
替换为更短的内容,但是当我输入make_iterator_range
时,我的编辑¹建议mir
完成。这对我来说很快
¹当然,那个编辑是Vim
答案 1 :(得分:5)
在基于范围的for
循环中,非成员begin()
和end()
的名称查找仅使用ADL。它不执行普通的非限定查找。 §6.5.4[stmt.ranged] /p1.3:
如果
_RangeT
是类类型,则会在类{{{{}}范围内查找 unqualified-id sbegin
和end
1}}好像通过类成员访问 查找(3.4.5),如果其中任何一个(或两个)找到至少一个 声明,[...]否则, begin-expr 和 end-expr 为
_RangeT
,begin(__range)
分别在end(__range)
和begin
中查找。end
和begin()
关联的命名空间(3.4.2)。 [注意:普通的非限定查询 (3.4.1)未执行。 - 结束记录]
因此,找不到您的end()
和{{1}}重载。
答案 2 :(得分:1)
根据T.C.'s answer,您无法获得免费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;
答案 3 :(得分:1)
我会扩展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
答案 4 :(得分:0)
由于Boost FOREACH宏使用C ++ 03声明和显式模板代码,因此它应该使用传统的查找规则而不是特殊的for
规则。
即使基于范围的for
可用,您也可以确保它扩展旧方式。
另一种方法是创建自己的类,该类派生自该对,但包含begin
和end
成员。然后写
for (e: mypair(p))
而不是
for (e: p)