2

我的代码基本上看起来像这样:

std::map<int, int> map1, map2;
BOOST_FOREACH(int i, map1)
{
    // do steps 1-5 here...
}
BOOST_FOREACH(int i, map2)
{
    // do steps 1-5 (identical to above) here...
}

有没有办法连接地图以消除第二个循环中的重复代码?或者一种扩展 BOOST_FOREACH 以一次性遍历两个不同地图的方法?显然我不想增加程序的时间复杂度(否则我可以创建一个新地图并插入其中 map1 和 map2)。我有一种感觉,我在这里遗漏了一些基本的东西。

4

6 回答 6

9

你可以定义一个函数:

typedef std::map<int, int> IntMap;

void doStuffWithInt(IntMap::value_type &i)
{
  // steps 1 to 5
}

BOOST_FOREACH(IntMap::value_type &i, map1)
  doStuffWithInt(i);
BOOST_FOREACH(IntMap::value_type &i, map2)
  doStuffWithInt(i);

尽管在这种情况下使用起来可能更简单std::for_each

for_each(map1.begin(), map1.end(), doStuffWithInt);
for_each(map2.begin(), map2.end(), doStuffWithInt);
于 2009-04-20T20:21:32.887 回答
3

这里的想法是编写一种特殊类型的迭代器来虚拟合并两个容器,就 BOOST_FOREACH 而言。请注意,我不是从现有的两个容器中创建新容器。我只是从第一个容器的 end() 跳转到第二个容器的 begin() 迭代器。我没有尝试编写实际的merged_iterator 类,但是虽然写起来可能有点长,但在技术上并不困难。我真的很惊讶没有使用谷歌找到类似的东西。不过,我并没有寻找太久!

template<typename Container>
boost::iterator_range<
  merged_iterator<Container::iterator>
  >
concat_containers( Container& c1, Container& c2 )
{
  typedef merged_iterator<typename Container::iterator> MergedIterator;
  typedef boost::iterator_range<MergedIterator> IteratorRange;
  return IteratorRange(
    MergeIterator( c1.begin(), c1.end(), c2.begin(), c2.end() ),
    MergeIterator( c2.end(), c1.end(), c2.begin(), c2.end() ) );
}

// Now use a bit of magic to define merged_iterator<...>
// And you'll be able to write

BOOST_FOREACH( std::pair<int, int> i, concat_containers( map1, map2 ) )
{
// Do whatever you want here
}
于 2009-04-20T21:40:01.963 回答
2

除了我推荐的 1800 解决方案之外,还有各种 hacky 解决方案:

for (int stage = 0; stage < 2; stage++) {
    BOOST_FOREACH(int i, stage == 0 ? map1 : map2) {
        ...
    }
}

typedef std::map<int, int> intmap;
std::vector<intmap *> v;
v.push_back(&map1);
v.push_back(&map2);
BOOST_FOREACH(intmap *m, v) {
    BOOST_FOREACH(int i, *m) {
        ...
    }
}

注意:当我看到同事写这样的代码时,有时我会被一种无法抗拒的想要扼杀他们的冲动所征服。使用风险自负。

于 2009-04-20T20:26:28.227 回答
1

最简单的方法是这样的:

std::map<int, int> map1, map2;
int key, value;
BOOST_FOREACH(boost::tie(key, value), boost::join(map1, map2))
{
    // do steps 1-5 here...
}

并且不要担心那些逗号不会因为括号而混淆预处理器。

于 2012-01-24T01:55:59.277 回答
0

在我的头顶,我会尝试

std::map<int, int> map1, map2;
std::map<int, int>& maps = { map1, map2 }
BOOST_FOREACH(std::map<int, int> map, maps)
  BOOST_FOREACH(int i, map)
  {
      // do steps 1-5 here...
  }
于 2010-03-02T10:15:40.403 回答
0

这里解释 了。

你可以这样做:

std::map<int,int> m;
typedef std::pair<int,int> pair_t;
BOOST_FOREACH(pair_t p, m)
于 2011-10-27T21:30:00.100 回答