Unc*_*ens 12
有一个问题,因为它是一个宏,因此无法处理包含逗号的类型(预处理器不了解模板).
您也可以在循环之前声明变量,请参阅文档.
std::map<int, double> my_map;
//1)
typedef std::pair<int, double> MyPair;
BOOST_FOREACH(MyPair p, my_map) { ... }
//2)
std::pair<int, double> p;
BOOST_FOREACH(p, my_map) { ... }
Run Code Online (Sandbox Code Playgroud)
编辑:
std::map特别是进一步的复杂化:value_type不是std::pair<Key, Value>,但是std::pair<const Key, Value>.
因此,如果你使用typedef,更合适的方式(如果你想在foreach循环中使用引用,唯一的方法)是使用
typedef std::pair<const int, double> MyPair;
//or
typedef std::map<int, double>::value_type MyPair;
BOOST_FOREACH(MyPair& ref, my_map) { ... }
Run Code Online (Sandbox Code Playgroud)
但是,如果要使用在循环之前声明的变量,那将无法工作,因为以后无法分配给std::pair<const int, double>实例(无法分配给const字段),在这种情况下,您只能使用pair<int, double>boost的手册显示.
如果你需要迭代一个映射,最简单的方法是使用元组,因为为了typedef得到正确的类型是很麻烦的.以下是如何使用元组:
std::map<int, double> my_map;
int key;
double value;
BOOST_FOREACH(boost::tie(key, value), my_map) { ... }
Run Code Online (Sandbox Code Playgroud)
请注意,逗号将在这里工作,因为括号放在键和值周围.预处理器只能理解逗号和括号(并且c99也要求它理解引号).因此,它不能解析<>在std::pair<int, double>.但是,我们可以使用括号来帮助预处理器.例如,如果我们有一个函数返回一个像这样调用的容器:
BOOST_FOREACH(int i, foo<int, int>()) { ... } //This won't compile
Run Code Online (Sandbox Code Playgroud)
因此,我们可以在表达式周围放置括号,它将有助于预处理器:
BOOST_FOREACH(int i, (foo<int, int>())) { ... } //This will compile
Run Code Online (Sandbox Code Playgroud)
但是,在地图的情况下,我们不能在声明周围放置括号(因为它不是表达式).所以这不起作用:
BOOST_FOREACH((std::pair<int, double> p), my_map) { ... } //This won't work
Run Code Online (Sandbox Code Playgroud)
因为它会转变成这样的东西(std::pair<int, double> p) = *it,当然,这是不正确的C++.但使用平局将起作用:
BOOST_FOREACH(tie(key, value), my_map) { ... } //This will work
Run Code Online (Sandbox Code Playgroud)
我们只需要在循环外声明键和值(如上所示).另外,它可以使循环具有更有意义的名称.你可以key代替p.first而value不是代替p.second.
BOOST_FOREACH_PAIR 是另一种在我们的经验中运作良好的选择:
http://lists.boost.org/Archives/boost/2009/09/156345.php
http://lists.boost.org/Archives/boost/2009/09/156366.php