以下来自手册:
缺陷
本节描述 BOOST_FOREACH
中的一些常见的缺陷。
带逗号的类型
由于 BOOST_FOREACH
是一个宏,它必须刚好有两个参数,并以一个逗号分隔它们。这并不总是很方便,尤其当循环变量的类型是一个模板的时候。考虑一下对 std::map
进行迭代:
std::map<int,int> m; // 错误!BOOST_FOREACH 宏参数过多。 BOOST_FOREACH(std::pair<int,int> p, m) // ...
一个解决方法是使用 typedef.
std::map<int,int> m; typedef std::pair<int,int> pair_t; BOOST_FOREACH(pair_t p, m) // ...
另一个解决方法是预先声明循环变量:
std::map<int,int> m; std::pair<int,int> p; BOOST_FOREACH(p, m) // ...
测试代码:
// boost_foreach_map.cpp : 定义控制台应用程序的入口点。
// BOOST_FOREACH缺陷
#include "stdafx.h"
#include <map>
#include <iostream>
#include <string>
#include <utility>
#include <vector>
#include <list>
#include <boost/foreach.hpp>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
map<int,string> map_list;
//map_list: (1,"11") (2,"22") (3,"33");
// map_list.insert(Pair(1, "11"));
// map_list.insert(Pair(2, "22"));
// map_list.insert(Pair(3, "33"));
map_list.insert(make_pair(1, "11"));
map_list.insert(make_pair(2, "22"));
map_list.insert(make_pair(3, "33"));
// map_list[1]="11";
// map_list[2]="22";
// map_list[3]="33";
// 不能放到BOOST_FOREACH括号中,模板参数过多,无法推导
// BOOST_FOREACH(const pair<int, string>& p, map_list) // 在内部定义,有错
// BOOST_FOREACH(const map<int, string>::value_type& p, map_list) // 有错
// map<int, string>::value_type p; //在BOOST_FOREACH中使用,有错
// map<const int, string>::value_type p; // 有错
// const map<int, string>::value_type p; // 有错
// pair<const int, string> p; // 有错, 奇怪的是,若使用typedef,正确
// const pair<int, string> p; // 有错
// const pair<const int, string> p; // 有错
pair<int, string> p; // 在外部定义,只有这种方式才正确
BOOST_FOREACH(p, map_list)
{
cout<<p.first<<" "<<p.second<<endl;
}
// typedef pair<int,string> Pair; // 正确
typedef pair<const int,string> Pair;
// 没有办法使用BOOST_FOREACH改变map的值,没办法定义非const引用
BOOST_FOREACH(const Pair& p, map_list) // 使用typedef,(Pair p, map_list):正确
{
cout<<p.first<<" "<<p.second<<endl;
}
// vector:无此缺陷
vector<int> vec(10,9);
BOOST_FOREACH(int i, vec)
{
i = 10; // 改变不作用于vector
}
BOOST_FOREACH(const int& i, vec)
{
cout<<i<<endl; // 9
}
BOOST_FOREACH(int& i, vec)
{
i = 10; // 改变作用于vector
cout<<i<<endl;
}
BOOST_FOREACH(const int i, vec)
{
cout<<i<<endl; // 10
}
return 0;
}