2

次のように、いくつかの画像を描画するアプリケーションに取り組んでいます。

void TimeSlice::draw(float fX, float fY) {
list<TimeSliceLevel*>::iterator it = levels.begin();
float level_x = x;
float level_y = y;
while(it != levels.end()) {
    (*it)->draw(level_x,level_y);
    level_y += (*it)->height;
    ++it;
}

}

これは少し間違っていますが。TimeSliceLevel* を X. に配置する必要がありfor(int i = 0; i < slices.size(); ++i)ます。ループがある場合は、 x = i * width. 私はイテレータを使用していますが、それは良いプログラミングだと何度も言われています :> そして、イテレータに新しい X 位置を計算するために使用できる何かの「インデックス」番号があるかどうか疑問に思っていますか? (したがって、イテレータの使用についての質問です)

敬具、ポルックス

4

6 に答える 6

7

イテレータは、順序付けされたインデックス付きリストの最初から最後までループする以外の目的で使用できるため、そうではありません。インデックスを個別に追跡し、パスごとにインクリメントする必要があります。

list<TimeSliceLevel*>::iterator it;
int index;

for(it = levels.begin(), index = 0; it != levels.end(); ++it, ++index) {
    ...
}
于 2010-06-12T18:19:10.607 に答える
3

いいえ、そうではありません。整数インデックスが必要な場合は、for ループを使用します。一部の反復子過激派があなたに信じ込ませようとしているものにもかかわらず、for ループは依然として C++ コードでその場所を占めています。

于 2010-06-12T18:18:35.403 に答える
2

イテレータ -> インデックスから移動できます。少なくとも 2 つの方法があります。

  1. -ランダム アクセス イテレータ (つまりi - container.begin())に使用します。
  2. std::distance(つまり)を使用しstd::distance(containter.begin(), i)ます。これはより「一般的な」ソリューションであり、-特殊化のおかげでランダム アクセス イテレータの場合でも同じように動作しますが、それ以外の場合はパフォーマンスにひどい影響を与えます。

ただし、コードが難読化される (そしてパフォーマンスが低下する可能性がある) ため、どちらもお勧めしません。他の人が言ったように、代わりに追加のカウンターを使用してください。必要に応じてインデックスを使用することに「問題」はありません。イテレータを優先することは、「一般的な」コードを記述するのに役立つガイドラインであることが意図されています。これにより、アルゴリズムを別のコンテナーまたはコンテナーのサブセットに適用できるようになります。等

于 2010-06-12T18:41:29.397 に答える
1

一部のイテレータ タイプでは、初期イテレータから現在のイテレータを単純に減算します。

index = it - levels.begin()

これは std::list イテレータでは機能しないため、上記の回答で述べたように、変数を使用してインデックスを明示的に追跡するだけです。イテレータとコンテナを使用する利点は失われません。コンテナが提供しない要件を追加しています。

于 2010-06-12T18:40:16.107 に答える
0

あなたは次のようなものを書かなければならないでしょう

size_t index = 0;
for (list<...>::const_iterator it = y.begin(); it != y.end(); ++it) {
   // Do your actions based on `index`
   ++index;
}

そして、まあ、これは時々適切です。

一方、アプリケーションをリファクタリング(再計画)して、実際の描画ループですべてを作成する必要x += something, y += something2, ...がなく、次のように動作させることができます。

foreach (Level* level, list) {
    level->draw(backend);
}

トリッキーな場合もありますが、私の考えでは、アプリケーションが「大きな」ものに成長した場合、このアプローチによって多くの時間を節約できます。

于 2010-06-12T18:24:31.740 に答える
0

ランダム アクセス イテレータの場合のみ可能です。ランダム アクセス イテレータの場合は、開始イテレータからイテレータを引いてインデックスを取得できます (別の int インデックス変数を保持する必要はありません)。

for (vector<int>::const_iterator cit = v.begin(); cit != v.end(); ++cit)
{
   cout << "This is element no: " << cit - v.begin() << endl;
}

あなたの例では、双方向イテレータのみである std::list を使用しているため、残念ながらそれを行うことはできません。std::vector を使用すると、私の例のように実行できます。

于 2010-06-12T18:39:18.043 に答える