2017-11-04 4 views
1

ベクトルを取り込み、単純に(手動で)反転する関数を作成しようとしています。私はreverse()の存在を認識していますが、「反復可能でないベクトルイテレータ」問題に遭遇しました。教育目的のために、その意味を知りたいと思います。私はこの問題を研究し、誰か(このフォーラムで)vect.end()は定義によって逆参照できないと言いましたが、私の理解から、reverse_iteratorを使うことは、 vect.rendは逆参照できません。逆反復可能でないベクトルイテレータ(手動で逆ベクトルを試みる)

vector<int> reverseVector(vector<int>); 

int main() 
{ 
    vector<int> vec; 

    for (int i = 0; i < 11; i++) 
    { 
     vec.push_back(i); 
    } 

    vec = reverseVector(vec); 

    for (vector<int>::iterator it = vec.begin(); it != vec.end(); it++) 
    { 
     cout << *it << " "; 
    } 
    cout << endl; 

    return 0; 
} 

vector<int> reverseVector(vector<int> vect) 
{ 
    vector<int>::reverse_iterator ritr; 
    for (ritr = vect.rbegin(); ritr != vect.rend(); ritr++) 
    { 
     vect.insert(vect.begin(), *ritr); 
     vect.pop_back(); 
    } 
    return vect; 
} 

答えて

1

は、逆方向イテレータを無効にします(背面からポップする)要素から要素を削除しています。


は、あなただけのベクトルの半分を反復処理し、このLKE、要素を入れ替えることができます:

void swap(int& a, int& b) { 
    int tmp = a; 
    a = b; 
    b = tmp; 
} 

vector<int> reverseVector(vector<int> vect) { 
    const size_t origin_size = vect.size(); 
    for(size_t i = 0; i < origin_size/2; ++i) 
     swap(vect[i], vect[origin_size - 1 - i]); 
    return vect; 
} 
1

あなたの問題は、逆参照性またはそれ以外の場合はrend()とは関係ありません。反復処理中にベクトルを変更すると、反復処理が無効になります。

元の質問に答えるために、reverse_iteratorは、フォワードイテレータと比較して「端を逆転する」だけではありません。 rbegin()end() - 1であり、rend()begin() - 1である。

1

あなたはベクトルに要素を追加した場合、ritrは、このようにdereferencableないエラー

ベクトルイテレータを無効にすることができます。

したがって、ループ変数としてインデックスを使用する方がよく、逆タスクのコピー(temp)ベクタを使用する方が優れています。

1

両方insertpop_backメンバ関数は、ベクトルを変更し、イテレータを無効にします。

1

デザイン上のヒント:実際にあなたが何をしているのかわからない限り、常に関数内でconst-referenceを使用してください。だから、このような罠に踏み込むことは避けてください。例:

vector<int> reverseVector(const vector<int> &vect) 

vectを変更できないため、この問題は発生しません。

関連する問題