劣化版iterator_traitsを実装してみる

前々回の記事で型変換について学習したのでVector等も渡せる配列操作関数を作成する - (void*)Pないとで出てきたiterator_traitsを実装してみる。

#include <iostream>
#include <vector>
using std::cout; using std::endl;

template<class T>
struct types {
    typedef typename T::value_type type;
};

template<class T>
struct types<T*> {
    typedef T type;
};

template<class Iterator>
Iterator myfind (Iterator first,Iterator last,typename types<Iterator>::type value) {
    Iterator p=first;
    for (; p != last; ++p) {
        if ( *p == value ) {
            break;
        }
    }
    return p;
}

int main () {
    std::vector<int> data;
    data.push_back(1);
    data.push_back(2);
    data.push_back(3);
    data.push_back(4);
    data.push_back(5);
    
    std::vector<int>::iterator it = myfind(data.begin(),data.end(),4);
    
    if ( it != data.end() ) {
        cout << *it << endl;
    }
}

一応、ちゃんと動いた。もちろん普通の配列を渡しても大丈夫。

色々複雑な想定を無視してるので型によってはまったくダメダメかしもれいないけどとりあえず解説。

まずvector等のクラスには元の型の情報をvalue_typeというtypedefされた値に格納されてるのでそれを返すようにする。

そしてそれ以外、つまり普通の配列が渡された場合、それは配列の先頭アドレスのポインタとなるのでそのポインタ型のポインタを外した型を返すようにすればOKということになります。



というところで、実際のiterator_traitsの実装を見てみようと思ったのですが、テンプレート構造が複雑過ぎてどこをどう見ればいいのかわからなかったので断念。