namespace my
{
// sub_string: part of a string, as delimited by a pair
// of iterators
struct sub_string//自定义容器
{
std::string::iterator begin;
std::string::iterator end;
/* ... implementation ... */
};
// Add overloads of range_begin() and range_end() in the
// same namespace as sub_string, to be found by Argument-Dependent Lookup.
//重载下面两个函数
inline std::string::iterator range_begin( sub_string & x )
{
return x.begin;
}
inline std::string::iterator range_end( sub_string & x )
{
return x.end;
}
// Also add overloads for const sub_strings. Note we use the conversion
// from string::iterator to string::const_iterator here.
//重载相应的const版本
inline std::string::const_iterator range_begin( sub_string const & x )
{
return x.begin;
}
inline std::string::const_iterator range_end( sub_string const & x )
{
return x.end;
}
}
namespace boost
{
// specialize range_mutable_iterator and range_const_iterator in namespace boost
//模板特化,让boost能够识别迭代器 , 很类似STL中的iterator_traits
template<>
struct range_mutable_iterator< my::sub_string >
{
typedef std::string::iterator type;
};
template<>
struct range_const_iterator< my::sub_string >
{
typedef std::string::const_iterator type;
};
}
使用my::sub_string substr;BOOST_FOREACH( char ch, substr ){ // Woo-hoo!}
当遍历map容器的时候,我们不能够这样调用
std::map<int,int> m; // ERROR! Too many arguments to BOOST_FOREACH macro. BOOST_FOREACH(std::pair<int,int> p, m) // ...因为BOOST_FOREACH是一个宏(macro),传递给它的参数不能过多,或者过于复杂,如果那样的话很可能会造成错误,
如果想要遍历一个map容器的话,一个好的办法就是使用typedef:
std::map<int,int> m; typedef std::pair<int,int> pair_t; BOOST_FOREACH(pair_t p, m) // ...另一个办法就是不要在BOOST_FOREACH里面定义变量,而是在外边定义好变量之后再传递进去:
std::map<int,int> m; std::pair<int,int> p; BOOST_FOREACH(p, m) // ...与普通遍历类似,当你在变量容器的时候例如vector,请不要在循环(loop)里面进行push_back之类会改变容器的操作,因为vector内部
其实是由3个指针来维护,当分配给vector的内存使用完之后它会自动进行调整,这就导致了原先传递给BOOST_FOREACH的迭代器无效,在对
vector进行insert ,eraser都可能使得vector的迭代器无效,所以请注意,下面的代码是错误的
std::vector<int> vect(4, 4); BOOST_FOREACH(int i, vect) { vect.push_back(i + 1); }