反復器アダプタ(二)general inserterの実現
6085 ワード
前節ではback_を実現しましたinserterとfront_Inserter、次はより一般的な挿入反復器で、ユーザーが挿入位置を指定できるようにします.
実装コードは次のとおりです.
付与操作は内部に格納された反復器を前に移動させ,++操作は同様に何もしなかったことがわかる.
付与オペレータで反復器を変更せずに++に変更してもいいですか?
答えは否定的だ.
想定は,先の想定通り実現されるが,ユーザが以下の操作を行った場合である.
では、最後の行がiterが指す位置が要素を挿入できることを保証することはできません.
では、上の書き方はどうしてできますか.なぜなら、insert操作を実行すると、最後の要素の次の位置、すなわち最初の不正な位置を指すend()という特殊な位置があるからです.これも唯一の合法的な不法な位置です.
上記のソースコードの実現によれば、付与時に反復器が前に移動するだけで、iter++は実質的な操作がなく、付与時に前に移動し、iterは実際に新しいend()位置を指し、ユーザーがどのように++操作を実行しても、iterの有効性に少しも影響しないことを保証する.
テストコードは次のとおりです.
実装コードは次のとおりです.
#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;
}