BOOST_FOREACH&没有typedef的模板

时间:2009-11-11 07:40:18

标签: c++ boost

当我使用BOOST_FOREACH时,简单的模板作为矢量没有问题。但是,当我尝试迭代地图>例如,我需要键入dede元素类型。

有解决方法吗?

4 个答案:

答案 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.firstvalue代替p.second

答案 2 :(得分:6)

BOOST_FOREACH_PAIR是另一种在我们的体验中运作良好的选择:

http://lists.boost.org/Archives/boost/2009/09/156345.php

http://lists.boost.org/Archives/boost/2009/09/156366.php

答案 3 :(得分:2)

这可以这么简单:

BOOST_FOREACH(auto& p, my_map) { ... }

使用C ++ 11标准,auto就像是C#中的var,它会做

BOOST_FOREACH(std::pair<int, double>& p, my_map) { ... }