次のようなことを行うために、マップ上のループの最後の反復にいるかどうかを判断するための最良の方法を見つけようとしています。
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
関数など。正規の方法は何ですか?
編集:マップのランダムアクセスイテレータはありません!
カノニカル?私はそれを主張することはできませんが、私は提案します
final_iter = someMap.end();
--final_iter;
if (iter != final_iter) ...
編集[〜#〜] ktc [〜#〜] 。(ありがとう!時々あなたはあまりにも速く行き、最も単純なことを台無しにします...)
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
}
}
少し前に質問されましたが、共有する価値があると思いました。
これは最も単純なようです:
bool last_iteration = iter == (--someMap.end());
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
}
}
Mark Ransomを変更して、実際に意図したとおりに機能するようにしました。
finalIter = someMap.end();
--finalIter;
if (iter != final_iter)
まだ誰もそれについて言及していないことに驚いたが、もちろんブーストには何かがある;)
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
}
}
次のコードはコンパイラーによって最適化されるため、パフォーマンスとOOPルール)によってこのタスクに最適なソリューションになります。
if (&*it == &*someMap.rbegin()) {
//the last iteration
}
Std :: mapには次のようなコード用の特別なメンバー関数rbeginがあるため、これはOOPルールによる最良のコードです。
final_iter = someMap.end();
--final_iter;
EOFを見つけて、何かを与えないようにする理由。
単に、それを除外します;
for (iter = someMap.begin(); someMap.end() - 1; ++iter) {
//apply to all from begin to second last element
}
KISS(KEEP IT SIMPLY SIMPLE)
#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が本当に小さい場合は、ラムダ関数を使用して&Fooの呼び出しを取り除くことができます。
シンプルでありながら効果的なアプローチ:
size_t items_remaining = someMap.size();
for (iter = someMap.begin(); iter != someMap.end(); iter++) {
bool last_iteration = items_remaining-- == 1;
}
これが私の最適化されたテイクです:
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);
これはどうですか、誰も言及していませんが...
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.。