2009-11-11 67 views

回答

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

你或许应该作出这样的:STD :: map :: value_type – 2009-11-11 08:59:01

+0

也在C++ 11中; BOOST_FOREACH(auto&ref,my_map){...} – 2011-11-11 10:11:24

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>中的<>。但是,我们可以使用括号来帮助预处理器。例如,如果我们有一个返回一个被称为像这样的集装箱AA功能:

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

+0

键和值之间的逗号会混淆预处理器。 – Ferruccio 2012-01-14 11:17:48

+0

@Ferruccio键和值之间的逗号将不会混淆预处理器,因为围绕键和值的括号。此外,当我需要迭代地图时,我一直在做这个。 – 2012-01-14 22:35:58

+0

我不知道你可以用预处理器做到这一点。 – Ferruccio 2012-01-15 12:02:41

2

这可能是如此简单:

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

使用C++ 11的标准,汽车就像是在C#变种,它会做

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