反復器アダプタ(二)general inserterの実現

6085 ワード

前節ではback_を実現しましたinserterとfront_Inserter、次はより一般的な挿入反復器で、ユーザーが挿入位置を指定できるようにします.
実装コードは次のとおりです.
#ifndef ITERATOR_HPP

#define ITERATOR_HPP



template <typename Container>

class InsertIterator

{

public:

    typedef typename Container::value_type value_type;

    typedef typename Container::iterator iterator;



    InsertIterator(Container &cont, iterator iter) :cont_(cont), iter_(iter) { }



    InsertIterator<Container> &operator=(const value_type &val)

    {

        cont_.insert(iter_, val);

        ++iter_;

        return *this;

    }



    InsertIterator<Container> &operator*()

    {

        return *this;

    }



    InsertIterator<Container> &operator++()

    {

        return *this;

    }

    InsertIterator<Container> &operator++(int)

    {

        return *this;

    }





private:

    Container &cont_;

    iterator iter_;

};



template <typename Container>

InsertIterator<Container> inserter(Container &c)

{

    return InsertIterator<Container>(c);

}





#endif //ITERATOR_HPP

付与操作は内部に格納された反復器を前に移動させ,++操作は同様に何もしなかったことがわかる.
付与オペレータで反復器を変更せずに++に変更してもいいですか?
答えは否定的だ.
想定は,先の想定通り実現されるが,ユーザが以下の操作を行った場合である.
iter++;

iter++;

iter++;

*iter = 2;

では、最後の行がiterが指す位置が要素を挿入できることを保証することはできません.
では、上の書き方はどうしてできますか.なぜなら、insert操作を実行すると、最後の要素の次の位置、すなわち最初の不正な位置を指すend()という特殊な位置があるからです.これも唯一の合法的な不法な位置です.
上記のソースコードの実現によれば、付与時に反復器が前に移動するだけで、iter++は実質的な操作がなく、付与時に前に移動し、iterは実際に新しいend()位置を指し、ユーザーがどのように++操作を実行しても、iterの有効性に少しも影響しないことを保証する.
テストコードは次のとおりです.
#include "Iterator.hpp"

#include <iostream>

#include <string>

#include <vector>

using namespace std;



template <typename T>

void printElems(const T &t, const string &s = "")

{

    cout << s << " ";

    for(typename T::const_iterator it = t.begin();

        it != t.end();

        ++it)

    {

        cout << *it << " ";

    }

    cout << endl;

}



int main(int argc, char const *argv[])

{

    vector<int> coll;

    coll.push_back(12);

    coll.push_back(34);

    coll.push_back(32);

    printElems(coll);





    inserter(coll, coll.begin()) = 99; 

    inserter(coll, coll.begin()) = 88;



    printElems(coll);



    inserter(coll, coll.end()) = 34; 

    inserter(coll, coll.end()) = 21;



    printElems(coll);



    return 0;

}