如何将 BOOST_FOREACH 与两个 std::map 一起使用?

发布于 2024-07-18 02:48:03 字数 364 浏览 5 评论 0原文

我的代码基本上如下所示:

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)。 我有一种感觉,我在这里缺少一些基本的东西。

I have code that looks essentially like this:

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...
}

Is there any way to concatenate the maps to eliminate the duplicate code in the second loop? Or a way to extend BOOST_FOREACH to iterate over two different maps in one go? Obviously I don't want to increase the time complexity of the program (otherwise I could just create a new map and insert into it map1 and map2). I have a feeling I am missing something rudimentary here.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

潇烟暮雨 2024-07-25 02:48:03

您可以定义一个函数:

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);

You could define a function:

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);

Although in that case it might be even simpler to use std::for_each:

for_each(map1.begin(), map1.end(), doStuffWithInt);
for_each(map2.begin(), map2.end(), doStuffWithInt);
你在看孤独的风景 2024-07-25 02:48:03

这里的想法是编写一种特殊类型的迭代器来虚拟地合并两个容器,就 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
}

The idea here is to write a special type of iterators to virtually merge two containers, as far as BOOST_FOREACH is concerned. Note that i am not creating a new container out of the two existing ones. I am simply jumping from the first container's end() to the second container's begin() iterator.
I did not try and write the actual merged_iterator class, but although it might a bit long to write, it's not technically difficult. I am actually surprised not to have found something like that using google. I did not look for long, though !

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
}
血之狂魔 2024-07-25 02:48:03

除了我推荐的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) {
        ...
    }
}

注意:当我看到同事这样写代码时,有时我会忍不住想掐死他们。 使用风险自负。

In addition to 1800's solution, which I would recommend, there's also various hacky solutions:

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) {
        ...
    }
}

Note: when I see colleagues write code like this, sometimes I am overcome by an irresistible urge to go strangle them. Use at your own risk.

过期以后 2024-07-25 02:48:03

最简单的方法是这样的:

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

不用担心这些逗号不会因为括号而使预处理器感到困惑。

The easiest way is like this:

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

And don't worry those commas won't confuse the preprocessor because of the parenthesis.

蒗幽 2024-07-25 02:48:03

在我的头顶上,我会尝试

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...
  }

Of the top of my head, I'd try

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...
  }
坦然微笑 2024-07-25 02:48:03

此处进行了解释

你可以这样做:

std::map<int,int> m;
typedef std::pair<int,int> pair_t;
BOOST_FOREACH(pair_t p, m)

It's explained here.

You can do this:

std::map<int,int> m;
typedef std::pair<int,int> pair_t;
BOOST_FOREACH(pair_t p, m)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文