0

特に配列からベクトルを構築する場合、ポインタとイテレータについて明確ではありません。

vectorについての説明から、それは言う

// the iterator constructor can also be used to construct from arrays:
int myints[] = {16,2,77,29};
std::vector<int> fifth (myints, myints + sizeof(myints) / sizeof(int) );    

プライマリでは、次のとおりです。

#include <vector>

int arr[ARR_LEN] = { /* Array elements */ };
std::vector<int> vecInt(arr, arr + ARR_LEN);

次のコンストラクタを使用していますか?

template <class InputIterator>
vector (InputIterator first, InputIterator last,
        const allocator_type& alloc = allocator_type());

もしそうなら、ここでは、(配列の) ポインタはランダムアクセス反復子に扱われ、入力反復子として扱われますか? コンパイラはこれをどのように行いますか? 他のコンテナからのイテレータを考慮すると、このイテレータの型は何ですか? たとえば、"array[int]"::iterator?

int arr[N] = {};
for (int i= 0; i<N; i++) {}

上記の代わりに、次のようなことができますか?

for (ItorType it=arr; it!=arr+N; ++it) { ... }
4

4 に答える 4

5

イテレータ テンプレートの引数は特定のクラスではありません。実際、名前はコンパイル プロセスに実質的な影響を与えません。代わりに、特定の反復子で使用できるメソッドを指定する特定の概念を参照します。RandomAccessIterator も InputIterator である必要があります。RandomAccessIterator の概念は、InputIterator の概念を改良したものです。

コンパイラーは、実際にはこれらの引数 (あなたの場合はポインター) を渡すだけです。std::vector<...>ポインターは RandomAccessIterator の概念を実装します。つまり、引用したコンストラクターで簡単に使用できます。ところで、この初期化を記述する適切な方法は

std::vector<int> vecInt(std::begin(arr), std::end(arr));

関数テンプレートbegin()end()は、C++ の最新バージョンに追加され、静的サイズの配列のサイズを推測します。あなたの例でサイズを決定するために使用される両方のアプローチは、いくつかの点で問題があります。

于 2013-09-27T14:26:05.693 に答える
2

次のコンストラクタを使用していますか?

はい。

もしそうなら、ここでは、(配列の) ポインタはランダムアクセス反復子に扱われ、入力反復子として扱われますか?

はい。

コンパイラはこれをどのように行いますか?

のような概念InputIteratorは、型がどのように振る舞わなければならないかについての非公式な仕様です。であるためには、値にアクセスするためのInputIterator間接参照 ( )と、次の値に移動するための*itインクリメント (++itおよび) をサポートする必要があります。it++であるためにはRandomAccessIterator、これらの演算に加えて、加算や減算などのいくつかの演算をサポートする必要があります。ポインターはこれらの要件を満たすため、イテレーターが必要な場所ならどこでも使用できます。

他のコンテナからのイテレータを考慮すると、このイテレータの型は何ですか? たとえば、"array[int]"::iterator?

ポインター を使用しint*て、配列 を反復処理しint[]ます。関数の引数として使用される場合 (ここのように)、または算術演算で使用される場合 ( などarr+N)、配列は最初の要素へのポインターに自動的に変換されます。

上記の代わりに、次のようなことはできますか?

はい。ItorTypeは、対応するポインター型になりint*ます。C++11 では、配列を含む任意の範囲の開始と終了を取得する関数がbeginあります。end

for (auto it = std::begin(arr); it != std::end(arr); ++it)

また、範囲ベースのループ:

for (int i : arr)
于 2013-09-27T14:29:47.200 に答える
1
template <class InputIterator>
vector (InputIterator first, InputIterator last,
        const allocator_type& alloc = allocator_type());

コンパイラがこのコンストラクタを使用するのは、単純に、このコンストラクタが両方の引数に同じ型を持つ 2 つの引数のコンストラクタであるためです。

引数が反復子である必要はありません。たとえば、次のように書くと

vector<int> x(3.0, 1.0);

コンパイラは同じコンストラクタを使用しようとします (double はイテレータのように使用できないため、コンパイル エラーが発生します)。

于 2013-09-27T14:23:46.190 に答える