【问题标题】:How to iterate over a std::map from start and end simultaneously?如何同时从开始和结束迭代 std::map?
【发布时间】:2021-07-15 11:58:32
【问题描述】:

我想同时遍历一个带有两个迭代器的地图,一个从开始,一个从结束,如下所示。

map<int, int> m;
for (auto i = m.begin(), j = m.rbegin(); i != m.end(), j != m.rend(); ++i, ++j) 
{
}

但出现以下错误。

error C3538: in a declarator-list 'auto' must always deduce to the same type

我还想迭代直到代码 sn-p 的i &lt; j。从地图的开始和结束都只到中间。

【问题讨论】:

  • i&lt;j 需要随机访问迭代器,而 map 没有。
  • 可能只是一个错字,但i != m.end(), j != m.rend() 应该是i != m.end() &amp;&amp; j != m.rend()。如所写,它相当于j != m.rend()
  • 如果你对这种模式有信心,你可以使用解构for ( auto [i, j] = make_tuple(m.begin(), m.rbegin()); i != m.end() &amp;&amp; j != m.rend(); ++i, ++j)。请注意,i != m.end(), j != m.rend() iteration expression 中的逗号运算符不会按照您的意愿(我认为)。

标签: c++ iterator stdmap


【解决方案1】:

std::map 迭代器是双向的,因此您根本不需要使用反向迭代器。

请注意,在幼稚的翻译中:

for (auto i = m.begin(), j = m.end(); i != m.end() && j != m.begin(); ++i, --j) 
{
}

您需要在正文中取消引用 (j-1)(这是反向迭代器为您处理的部分)。


我也想迭代直到 i

i == j但是 ...你必须小心你的增量和减量时,你绝对可以停止。

类似:

for (auto i = m.begin(), j = m.end();
     i != j && std::next(i) != j;
     ++i, --j) 
{
}

可能有效,但请仔细检查具有零、一、二元素的容器的逻辑,并准确决定应该在这些情况下发生什么。

【讨论】:

  • 干杯,我知道在那一点上我至少会弄错一个细节。
  • 干杯,我不知道,但你的回答让我意识到我的第一次尝试是错误的 :)
【解决方案2】:

for 循环的 init 语句可以为空。要将变量限制在尽可能窄的范围内,我建议添加一些额外的{}。可以通过base()从反向迭代器中获取正向迭代器,然后比较两者:

map<int, int> m;
{
    auto i = m.begin();
    auto j = m.rbegin();
    for (; i != j.base() && i != std::next(j.base()); ++i, ++j) 
    {
        std::cout << i->first << " " << j->first << "\n";
    }
}

Live Demo

作为Useless explains nicely,您需要小心并行递增迭代器并通过!= 比较它们。实际上,当您想以这种方式迭代其元素时,有人可能会争辩说您使用了错误的容器。按顺序迭代元素不是std::maps 的强项。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-30
    • 2011-01-23
    • 2011-03-07
    相关资源
    最近更新 更多