## 2.4 挿入反復子

出力反復子の間接参照された値への代入は、通常、既存の位置の内容を上書きするために使用されます。たとえば、次の関数 `copy()` の呼出しは 1 つのベクトルから他のベクトルへ値を転送しますが、宣言文によって初期化された場合でも、2 番目のベクトルの空白文字は無視されます。

    vector<int> a(10);
    vector<int> b(10);
       ...
    copy (a.begin(), a.end(), b.begin());

リストなどの構造体であっても、この形式で上書きすることができます。次のコードでは、`c` という名前のリストに少なくとも 10 個の要素があると仮定します。リストの最初の 10 個のロケーションがベクトル `a` の内容に置換されます。

    list<int> c;
       ...
    copy (a.begin(), a.end(), c.begin());

新しい要素が追加されると動的に拡大されるリストやセットなどの構造体を使用する場合、既存のロケーションを上書きするよりも、構造体に新しい値を挿入するほうが適切である場合があります。挿入反復子と呼ばれる型のアダプタを使用すると、コンテナの要素を上書きせずに、`copy()` などのアルゴリズムを使用して関連付けられたコンテナに挿入することができます。反復子の出力演算は、関連付けられたコンテナへの挿入に変更されます。たとえば、次のコードはベクトル `a` の値を宣言された空のリストに挿入します。

    list<int> d;

    copy (a.begin(), a.end(), front_inserter(d));

挿入反復子には 3 つの形式があり、そのいずれも、copy 演算を insert 演算に変更するために使用することができます。上記の `front_inserter` を使用して生成された反復子は、値をコンテナの先頭に挿入します。`back_inserter` によって生成された反復子は、要素をコンテナの末尾に配置します。どちらの形式も、list や deque と共に使用することができますが、set や map と共に使用することはできません。反復子 `back_inserter` は vector と共に使用することができますが、`front_inserter` は vector と共に使用することはできません。

3 番目の最も一般的な形式の挿入反復子は `inserter` であり、コンテナとコンテナ内の反復子の 2 つの引数を使用します。この形式では、要素がコンテナ内の指定されたロケーションにコピーされます(list の場合は、指定されたロケーションの直前に要素がコピーされることを意味します)。この形式は前述の 2 つの形式が動作するすべての構造体で使用でき、set や map と共に使用することもできます。

次の単純なプログラムでは、3 つの形式の挿入反復子の使用を示します。まず、値 3、2、1 が空のリストの先頭に挿入されます。値が挿入されるたびに、その値が新しい先頭となり、結果として生じるリストは 1、2、3 という順序になります。次に、値 7、8、9 がリストの末尾に挿入されます。最後に、`find()` 演算が使用され、値 7 を示す反復子が配置され、数値 4、5、6 がその直前に挿入されます。結果として生じるリストは、1 から 9 の順序となります。

    void main() {
       int threeToOne [ ] = {3, 2, 1};
       int fourToSix [ ] = {4, 5, 6};
       int sevenToNine [ ] = {7, 8, 9};

       list<int> aList;

                              // まず、先頭に挿入する
                              // 各値が新しく先頭になる
       copy (threeToOne, threeToOne+3, front_inserter(aList));

                              // 次に、末尾に挿入する
       copy (sevenToNine, sevenToNine+3, back_inserter(aList));

                              // 7 を検出し、中間に挿入する
       list<int>::iterator seven = find(aList.begin(), aList.end(), 7);
       copy (fourToSix, fourToSix+3, inserter(aList, seven));

                              // 結果を出力へコピーする
       copy (aList.begin(), aList.end(),
             ostream_iterator<int,char>(cout, " "));
       cout << endl;
    }

`inserter(aList, aList.begin())` で作成された反復子と `front_inserter(aList)` で作成された反復子には、わずかながら重要な違いがあることに注意してください。`inserter(aList, aList.begin())` が呼び出されると、シーケンスの値がコピーされ、各値がリストの先頭に追加されます。一方、`front_inserter(aList)` が呼び出されると、値がコピーされ、各値が新しく先頭となります。その結果、`front_inserter(aList)` では元のシーケンスの順序が逆になり、`inserter(aList, aList.begin())` では元の順序が維持されます。

Copyright (c) 1998, Rogue Wave Software, Inc.
このマニュアルに関する誤りのご指摘やご質問は、電子メールにてお送りください。
OEM リリース, 1998 年 6 月