2012-04-27 4 views
2

ベクトルのイテレータがあります。どのインデックスがイテレータを指しているのか知りたいだから私は次のようにしたが、わからない。どのインデックスがイテレータを指しているか

int temp = -1; 
std::vector <int> ::iterator f; 

for (f=eFace[e].begin(); f!=eFace[e].end(); ++f) 
{ 
    if (*f == face) 
{ 
    switch (f-eFace[e].begin()) 
    { 
     case 0: 
     temp = 5;         
     break; 
     case 1: 
     temp = 3; 
     break; 
     case 2: 
     temp = 4; 
     break; 
     case 3: 
     temp = 1; 
     break; 
     case 4: 
     temp = 2; 
     break; 
     case 5: 
     temp = 0; 
     break; 
      default: 
     throw; 
    } 

    break; 
    } 
} 
+1

あなたの大きな目標は何ですか?あなたはイテレーターとインデックスを同時に必要としていますか? –

+0

@phresnel、私はこれが出力のために最も有用だと思います。私は目標が同じであると推測します。 – chris

答えて

2

なぜこのような何か:あなたの質問のために

std::vector <int> ::iterator f; 

int index = 0; 

for (f=eFace[e].begin(); f!=eFace[e].end(); ++f) 
{ 
    // do sth 

    index++; 
} 
+1

@larsmans:インクリメントは一定の時間操作です。 –

+1

そして、より大きなループでは、毎回距離を減算/呼出することと比較して、これにはかなりの時間差があります。 – chris

+2

'f'のインクリメントと並んで' index'のインクリメントを入れて同期が外れないようにするのはなぜですか? @MatthieuM。 –

4
std::vector<int>::size_type index = std::distance (eFace [e].begin(), f); 

あなたががそれをすべてのループを実行した場合、これは遅くなることに注意してください。ベクトルのための別のオプションは、次のようになります。

std::vector<int>::size_type index = f - eFace [e].begin(); 

ベクトルは以下のスティーブ・ジェソップで指摘したように、減算が定義されているために必要とされるランダム・アクセス反復子を使用しているため、この作品。

+0

実際には標準で必要かどうかは分かりませんが、 'std :: distance'にはランダムアクセスとしてタグ付けされたイテレータ(ベクトルイテレータ)が一定の複雑さを持っていないと、準拠しています。ランダムアクセスイテレータの減算は 'b-a ==(a

+0

@SteveJessop、それは興味深い点です。私は減算がそのように実装されていることに気づいていませんでした。私の答えは、インデックス変数を設定し、それを増分する2つの異なる部分よりも、1行でのアプローチを指していました。より大きなループではむしろ非効率的です。 – chris

+0

実際には、減算*はそのように実装されているわけではありません。結果がその値として標準で定義されていることだけです。だから、もし我々が愚かに遅い実装の '距離'について推測しているなら、減算も愚かだと推測することができます。実際には、実際の使用に適した実装ではどちらも高速に動作します。 Btw、ベクトルの減算を行うのは、記憶域が連続しているわけではなく、反復子がランダムアクセスであり、したがって減算が定義されていなければならないということです。例えば、 'deque'は非連続的な記憶域を使用しますが、イテレータの減算もそれに対応します。 –

0

「私は、反復子が指しんどの指標を知りたいです。」 std::vector<int>::iterator f = eFace.begin();と言って、インデックスアプローチに似ているインターレーターをstd::vector<int>::size_type i = 0;という形で作成しています。あなたはeFace.begin()!= eFace.end()forループとベクトルを歩いたときにi = 0!= eFace.size()を使用するのと同じ方法を使用するイテレータで

少なくとも私はあなたの元の質問があったと思います。

2

もっと明確なコードを取得する方がずっと簡単です。

まず、ベクトルの値を見つける:

// Returns the index of `face` in `vec`. 
// If `face` is not present in `vec`, returns `vec.size()`. 
size_t findFaceIndex(int const face, std::vector<int> const& vec) { 
    std::vector<int>::const_iterator const it = 
     std::find(vec.begin(), vec.end(), face); 

    return it - vec.begin(); 
} 

そして今マッピング:

static int const FaceMap[] = { 5, 3, 4, 1, 2, 0 }; 
static size_t const FaceMapSize = sizeof(FaceMap)/sizeof(int); 

// Translate face index into ... 
int faceIndexToX(size_t const index) { 
    if (index >= FaceMapSize) { throw std::runtime_error("out of bounds"); } 
    return FaceMap[index]; 
} 
+0

それらの最初のものは、もちろん、テンプレート化することができます。一般的に誰かが線形検索を使うときにstd :: findを使うならば、警告サインがあります。それはまれにしか十分ではありませんが、小規模なコレクションはまれです。 あなたの2番目の解決策は、std :: runtime_exception(例外はありませんが、runtime_errorはありますが、std :: out_of_rangeはおそらくベクトルのようにスローする方が良いでしょう。 – CashCow

+0

@CashCow:私は 'std :: array'と考えましたが、OPがC++ 11に精通しているかどうかはわかりません。 –

0

とにかくイテレータを持っているときに、配列のインデックスを必要とする理由かしら?イテレータがランダムアクセスの場合はから削除しますが、インデックスが非常に重要な場合は、イテレータではなくそのコードを使用する方がよいでしょうか?もちろん、コードにアクセスできるかどうかによって異なりますそれをリファクタリングする

私はあなたのスイッチで達成しようとしていることはよく分かりませんが、値をマップするのであれば、おそらく疎ベクトルがはるかに適切でしょうか?

関連する問題