C++ 如何检测 std::map 循环中的最后一次迭代?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/151046/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 13:15:42  来源:igfitidea点击:

How can I detect the last iteration in a loop over std::map?

c++stliteratormaps

提问by cdleary

I'm trying to figure out the best way to determine whether I'm in the last iteration of a loop over a map in order to do something like the following:

我试图找出确定我是否处于地图循环的最后一次迭代中的最佳方法,以便执行以下操作:

for (iter = someMap.begin(); iter != someMap.end(); ++iter) {
    bool last_iteration;
    // do something for all iterations
    if (!last_iteration) {
        // do something for all but the last iteration
    }
}

There seem to be several ways of doing this: random access iterators, the distancefunction, etc. What's the canonical method?

似乎有几种方法可以做到这一点:随机访问迭代器、distance函数等。规范方法是什么?

Edit: no random access iterators for maps!

编辑:地图没有随机访问迭代器!

采纳答案by Mark Ransom

Canonical? I can't claim that, but I'd suggest

典范?我不能声称,但我建议

final_iter = someMap.end();
--final_iter;
if (iter != final_iter) ...

Editedto correct as suggested by KTC.(Thanks! Sometimes you go too quick and mess up on the simplest things...)

按照KTC 的建议进行编辑以更正(谢谢!有时你走得太快,把最简单的事情搞砸了……)

回答by dutchdukes

Since C++11, you can also use std::next()

从 C++11 开始,您还可以使用 std::next()

   for (auto iter = someMap.begin(); iter != someMap.end(); ++iter) { 
        // do something for all iterations
        if (std::next(iter) != someMap.end()) {
            // do something for all but the last iteration
        }
    }

Although the question was asked a while ago, I thought it would be worth sharing.

虽然这个问题是前一段时间提出的,但我认为值得分享。

回答by Torlack

This seems like the simplest:

这似乎是最简单的:

bool last_iteration = iter == (--someMap.end());

回答by camh

If you just want to use a ForwardIterator, this should work:

如果您只想使用 ForwardIterator,这应该可以工作:

for ( i = c.begin(); i != c.end(); ) {
        iterator cur = i++;
        // do something, using cur
        if ( i != c.end() ) {
                // do something using cur for all but the last iteration
        }
}

回答by KTC

Modified Mark Ransom's so it actually work as intended.

修改了 Mark Ransom 使其真正按预期工作。

finalIter = someMap.end();
--finalIter;
if (iter != final_iter)

回答by Pieter

Surprised no one mentioned it yet, but of course boost has something ;)

令人惊讶的是还没有人提到它,但当然 boost 有一些东西;)

Boost.Next(and the equivalent Boost.Prior)

Boost.Next(以及等效的 Boost.Prior)

Your example would look like:

您的示例如下所示:

for (iter = someMap.begin(); iter != someMap.end(); ++iter) {
    // do something for all iterations
    if (boost::next(iter) != someMap.end()) {
        // do something for all but the last iteration
    }
}

回答by mpoleg

The following code would be optimized by a compiler so that to be the best solution for this task by performance as well as by OOP rules:

以下代码将由编译器优化,以便根据性能和 OOP 规则成为此任务的最佳解决方案:

if (&*it == &*someMap.rbegin()) {
    //the last iteration
}

This is the best code by OOP rules because std::map has got a special member function rbegin for the code like:

这是 OOP 规则的最佳代码,因为 std::map 有一个特殊的成员函数 rbegin 用于如下代码:

final_iter = someMap.end();
--final_iter;

回答by Angelin Nadar

Why to work to find the EOF so that you dont give something to it.

为什么要努力找到EOF,这样你就不会给它一些东西。

Simply, exclude it;

简单地说,排除它;

for (iter = someMap.begin(); someMap.end() - 1; ++iter) {
    //apply to all from begin to second last element
}

KISS (KEEP IT SIMPLY SIMPLE)

吻(保持简单)

回答by paxos1977

#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <algorithm>

using namespace boost::lambda;

// call the function foo on each element but the last...
if( !someMap.empty() )
{
  std::for_each( someMap.begin(), --someMap.end(), bind( &Foo, _1 ) );
}

Using std::for_each will ensure that the loop is tight and accurate... Note the introduction of the function foo() which takes a single argument (the type should match what is contained in someMap). This approach has the added addition of being 1 line. Of course, if Foo is really small, you can use a lambda function and get rid of the call to &Foo.

使用 std::for_each 将确保循环紧密而准确...注意函数 foo() 的引入,它接受一个参数(类型应该与 someMap 中包含的内容相匹配)。这种方法增加了 1 行。当然,如果 Foo 真的很小,您可以使用 lambda 函数并摆脱对 &Foo 的调用。

回答by alfred

For someone who likes C++11 range-based loop:

对于喜欢 C++11 基于范围循环的人:

    for (const auto& pair : someMap) {
      if (&pair != &*someMap.rbegin()) ...
    }

Notice only reference type works here, not auto pair

注意这里只有引用类型有效,而不是 auto pair