我正在试图找出确定我是否在地图循环的最后一次迭代中的最佳方法,以便执行以下操作:
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
}
}
似乎有以下几种方法:随机访问迭代器,distance
函数等。规范方法是什么?
编辑:没有地图的随机访问迭代器!
答案 0 :(得分:25)
典型?我不能声称,但我建议
final_iter = someMap.end();
--final_iter;
if (iter != final_iter) ...
已编辑按照 KTC的建议进行更正。(谢谢!有时候你走得太快,搞砸了最简单的事情......)
答案 1 :(得分:16)
从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
}
}
虽然问题是在不久前提出的,但我认为值得分享。
答案 2 :(得分:14)
这似乎是最简单的:
bool last_iteration = iter == (--someMap.end());
答案 3 :(得分:10)
如果您只想使用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
}
}
答案 4 :(得分:6)
修改了Mark Ransom,所以它实际上按预期工作。
finalIter = someMap.end();
--finalIter;
if (iter != final_iter)
答案 5 :(得分:6)
感到惊讶没有人提到它,但当然提升有一些东西;)
Boost.Next(和等效的Boost.Prior)
您的示例如下:
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
}
}
答案 6 :(得分:3)
以下代码将由编译器优化,以便通过性能和OOP规则成为此任务的最佳解决方案:
if (&*it == &*someMap.rbegin()) {
//the last iteration
}
这是OOP规则的最佳代码,因为std :: map有一个特殊的成员函数rbegin代码如下:
final_iter = someMap.end();
--final_iter;
答案 7 :(得分:1)
#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 ) );
}
使用std :: for_each将确保循环紧凑且准确...注意引入函数foo(),该函数采用单个参数(类型应与someMap中包含的类型匹配)。这种方法增加了1行。当然,如果Foo非常小,你可以使用lambda函数来摆脱对&amp; Foo的调用。
答案 8 :(得分:1)
为什么要努力寻找EOF,以免你给它一些东西。
简单地说,排除它;
for (iter = someMap.begin(); someMap.end() - 1; ++iter) {
//apply to all from begin to second last element
}
亲吻(保持简单易行)
答案 9 :(得分:0)
一种简单而有效的方法:
size_t items_remaining = someMap.size();
for (iter = someMap.begin(); iter != someMap.end(); iter++) {
bool last_iteration = items_remaining-- == 1;
}
答案 10 :(得分:0)
这是我的优化服务:
iter = someMap.begin();
do {
// Note that curr = iter++ may involve up to three copy operations
curr = iter;
// Do stuff with curr
if (++iter == someMap.end()) {
// Oh, this was the last iteration
break;
}
// Do more stuff with curr
} while (true);
答案 11 :(得分:0)
怎么样,没有人提到......
for (iter = someMap.begin(); iter != someMap.end(); ++iter) {
// do something for all iterations
if (iter != --someMap.end()) {
// do something for all but the last iteration
}
}
这看起来很简单,mm ......
答案 12 :(得分:0)
对于喜欢C ++ 11基于范围的循环的人:
for (const auto& pair : someMap) {
if (&pair != &*someMap.rbegin()) ...
}
请注意,仅引用类型在此起作用,auto pair
答案 13 :(得分:-1)
完整计划:
#include <iostream>
#include <list>
void process(int ii)
{
std::cout << " " << ii;
}
int main(void)
{
std::list<int> ll;
ll.push_back(1);
ll.push_back(2);
ll.push_back(3);
ll.push_back(4);
ll.push_back(5);
ll.push_back(6);
std::list<int>::iterator iter = ll.begin();
if (iter != ll.end())
{
std::list<int>::iterator lastIter = iter;
++ iter;
while (iter != ll.end())
{
process(*lastIter);
lastIter = iter;
++ iter;
}
// todo: think if you need to process *lastIter
std::cout << " | last:";
process(*lastIter);
}
std::cout << std::endl;
return 0;
}
该计划产生:
1 2 3 4 5 | last: 6
答案 14 :(得分:-2)
你可以在迭代之前从地图中拉出一个元素,然后在循环中执行“最后一次迭代”工作,然后将元素放回到地图中。这对于异步代码来说非常糟糕,但考虑到C ++的其余部分对于并发有多糟糕,我认为这不是一个问题。 : - )