没有typedef的BOOST_FOREACH和模板

Ant*_*kov 10 c++ boost

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

有没有解决方法?

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的手册显示.


Pau*_* II 8

如果你需要迭代一个映射,最简单的方法是使用元组,因为为了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.firstvalue不是代替p.second.