3

次の非常に基本的な質問があります。関数内の配列を埋めるために、従来の C 型ポインターの代わりに stl イテレーターを使用したいと考えています。C スタイルの方法で、次の例を意味します。

void f(double* v, size_t n) {
    for (int i = 0; i < n; i++) 
         v[i] = 10;    /* a more reasonable value in practice! */
}

次のようにイテレータを使用して、これを C++ スタイルに変換します。

void f(vector<double>::const_iterator first, vector<double>::const_iterator last) {
    for(vector<double>::iterator it =  first; it != last; it++)
        *it = 10;
}

しかし、コンパイルエラーが発生します。iterator代わりに使用すればconst_iterator問題は解決します。しかし、それが正しい方法であるかどうか疑問に思っていましたか?私が考えたのでvector.begin()vector.end()イテレータは定数です。

前もって感謝します!

4

5 に答える 5

5

の違い

const vector<double>::iterator

vector<double>::const_iterator

double * const vと の間とほぼ同じconst double *vです:

  • 最初のものは、イテレータは一定のままでなければならないと言っていますが、それが指すものは変更できます
  • 2 番目は、イテレータ自体は変更可能であると述べていますが、それが指しているのはconstです。

関数を次のように書き換えると

void f(const vector<double>::iterator first, const vector<double>::iterator last) {
    for(vector<double>::iterator it =  first; it != last; it++)
        *it = 10;
}

正しくコンパイルおよび実行されます。

于 2013-08-14T14:59:11.433 に答える
4

これは、 がconst_iteratorconst へのポインタにほぼ対応しているためです。したがって、反復子の値を変更する、つまり別の場所を指すようにすることはできますが、それが指すものを変更することはできません。

これは、インクリメントまたはデクリメントを許可しない const イテレータとは異なります。次に例を示します。

#include <vector>

int main() {
  std::vector<int> v{ 1, 2, 3 };

  std::vector<int>::const_iterator i = v.begin();
  *i = 10;                                         // ERROR!
  ++i;                                             // OK

  std::vector<int>::iterator const ci = v.begin();
  *ci = 10;                                        // OK
  ++ci;                                            // ERROR!
}
于 2013-08-14T14:58:12.987 に答える
0

sを使用しているconst_iteratorため、ベクトルを変更することはできません。非 const を使用するiteratorのは正しいことです。

あなたの最後の質問に答えて、実装vector.begin()と非実装vector.end()の両方があります。ベクトルが非 const の場合、非反復子が得られます。std::vector::beginのドキュメントを参照してください。const_const_const_

于 2013-08-14T14:58:47.680 に答える
0

問題は、関数がs を取ることですが、データを変更するconst_iterator必要があるため、ループに が必要です。iterator明らかに範囲を変更することを意図しているため、解決策はもちろん、関数がiteratorすぐに s を取るようにすることです。

vector.begin()これは、返されるものとは何の関係もありません。constオブジェクトまたは参照の場合は s を返し、const_iteratorそれ以外の場合は s を返しますiteratoriteratorただし、渡された範囲の値を変更するため、関数には s が必ず必要です。

于 2013-08-14T15:00:47.013 に答える