当我使用BOOST_FOREACH时,简单的模板作为矢量没有问题。但是,当我尝试迭代地图>例如,我需要键入dede元素类型。
有解决方法吗?
答案 0 :(得分:12)
有一个问题,因为它是一个宏,因此无法处理包含逗号的类型(预处理器不了解模板)。
您也可以在循环之前声明变量,请参阅documentation。
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) { ... }
修改强>
特别是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) { ... }
但是,如果要使用在循环之前声明的变量,那将无法工作,因为您以后无法分配给std::pair<const int, double>
实例(无法分配给const字段),其中例如,您只能使用pair<int, double>
作为助手的手册。
答案 1 :(得分:8)
如果你需要迭代一个地图,最简单的方法是使用元组,因为为typedef获取正确的类型是很麻烦的。以下是如何使用元组:
std::map<int, double> my_map;
int key;
double value;
BOOST_FOREACH(boost::tie(key, value), my_map) { ... }
请注意,逗号将在这里工作,因为括号放在键和值周围。预处理器只能理解逗号和括号(并且c99也要求它理解引号)。因此,它无法解析<>
中的std::pair<int, double>
。但是,我们可以使用括号来帮助预处理器。例如,如果我们有一个函数返回一个像这样调用的容器:
BOOST_FOREACH(int i, foo<int, int>()) { ... } //This won't compile
因此,我们可以在表达式周围放置括号,它将有助于预处理器:
BOOST_FOREACH(int i, (foo<int, int>())) { ... } //This will compile
但是,在地图的情况下,我们不能在声明周围放置括号(因为它不是表达式)。所以这不起作用:
BOOST_FOREACH((std::pair<int, double> p), my_map) { ... } //This won't work
因为它会转变成类似(std::pair<int, double> p) = *it
的东西,当然,这是不正确的C ++。但使用平局将起作用:
BOOST_FOREACH(tie(key, value), my_map) { ... } //This will work
我们只需要在循环外声明键和值(如上所示)。另外,它可以使循环具有更有意义的名称。您可以写key
代替p.first
,value
代替p.second
。
答案 2 :(得分:6)
BOOST_FOREACH_PAIR
是另一种在我们的体验中运作良好的选择:
答案 3 :(得分:2)
这可以这么简单:
BOOST_FOREACH(auto& p, my_map) { ... }
使用C ++ 11标准,auto就像是C#中的var,它会做
BOOST_FOREACH(std::pair<int, double>& p, my_map) { ... }