【问题标题】:Using Structured binding declaration in Range-based for loop在基于范围的 for 循环中使用结构化绑定声明
【发布时间】:2020-07-13 07:45:57
【问题描述】:

我正在尝试将两个 std::map 容器(例如 std::map<int, int> foo, bar)组合成第三个 std::map(例如 std::map<int, int> foobar)。

我知道我可以使用以下迭代器来实现这一点:

    std::map<int, int>::iterator itr1 = foo.begin();
    std::map<int, int>::iterator itr2 = bar.begin();

    for (; itr1 != foo.end() && itr2 != bar.end(); ++itr1, ++itr2) 
    {
      foobar[itr1->first] += itr1->second;
      foobar[itr2->first] += itr2->second;
    }

但是我如何使用基于范围的 for 循环(也许,结合结构化绑定声明)来实现相同的效果?

或者有没有更好的方法来组合这两个关联容器?

编辑:这个问题的预期答案应该采用两个容器(此处为std::map)并将它们组合成一个联合/联合映射,其中键来自各自的关联容器和添加的重复键的值。

示例: 如果给定std::map 容器foobar 是:

  std::map<int, int> foo = {{1, 10}, {2, 20}, {3, 30}};
  std::map<int, int> bar = {{3, 50}, {4, 60}};

那么 `foobar' 应该是:

  std::map<int, int> foobar = {{1, 10}, {2, 20}, {3, 80}, {4, 60}};

这一切都在一个单个基于范围的 for 循环中完成

【问题讨论】:

标签: c++ for-loop c++17 structured-bindings


【解决方案1】:

有没有更好的方法来组合这两个关联容器?

最简单的方法可能是分别迭代它们:

for(auto[k, v] : foo) foobar[k] += v;
for(auto[k, v] : bar) foobar[k] += v;

如果你想丢弃foobar中已有的任何数据:

foobar = foo;
for(auto[k, v] : bar) foobar[k] += v;

【讨论】:

  • 感谢您的回答,尽管您的回答不会产生与问题中发布的代码 sn-p 相同的结果。
  • @radon 哦,对了。我刚读了“结合”,并认为这是关于工会的。我进行了编辑。
  • 我认为你在以前的版本中是对的,第一个循环可能只是复制构造函数。
  • @Bob__ 也许-但问题中没有任何内容显示foobar是否已经包含任何内容。如果是这种情况,这个版本应该可以工作。
【解决方案2】:

有一个标准库算法可以做到这一点:std::set_union,在&lt;algorithm&gt;。现在,当然,它很丑,因为它使用迭代器对,但您可能可以使用范围来改进它。

无论如何:

std::set_union(
    foo.begin(), foo.end(), 
    bar.begin(), bar.end(),
    std::inserter(foobar, foobar.begin())
);

应该可以解决问题。


PS - 这可能有点慢 - 如std::map itself is really slow。我假设你不关心这张地图的性能(或者它真的更小),否则你不应该使用它。

【讨论】:

  • 您的代码生成: foobar = {{1, 10}, {2, 20}, {3, 30}, {4, 60}};预期的 foobar = {{1, 10}, {2, 20}, {3, 80}, {4, 60}};
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-31
  • 1970-01-01
  • 2013-01-04
  • 2015-11-29
  • 1970-01-01
  • 2016-04-03
相关资源
最近更新 更多