連想コンテナとポインタ


連想コンテナ、例えばsetの要素にポインタを使いたいとき、
predは自分で書かなくちゃあかん。

string StringPtrLess
{
    bool operator()( const string* lhs , const string* rhs )
    {
        return *lhs < *rhs;
    }
};

set< string* , StringPtrLess > str_set;


EffectiveSTL
第20項 ポインタの連想コンテナに対する比較の種類を指定しよう
によると、
このStringPtrLessは以下のようなテンプレートに書き換えると応用がきくぜ。

struct DereferenceLess
{
    template <typename PtrType>
    bool operator() (PtrType pt1 , PtrType pt2)const
    {
        return *pt1 < *pt2;
    }
};

おおー。おおー。


あと、こんな事したい時。

set< string* , StringPtrLess > str_set;

//文字をインサートぅ!


//アウトー
copy( str_set.begin() , str_set.end() , ostream_iterator<string>(cout , "\n" ) );

典型的なパターンだけどアウト。


こいつもテンプレートを利用して逆参照ファンクタクラスを作って、
transformを使うとOK!

struct Dereference
{
    template <typename T>
    const T& operator()( const T* ptr) const
    {
        return *ptr;
    }
};

set< string* , StringPtrLess > str_set;

transform( str_set.begin() , str_set.end() , ostream_iterator<string>(cout , "\n" ) , Dereference() );

おおー。おおー。transformを使えばいいのか!
今まで逆参照ファンクタクラスの発想が無かったのでfor文で回してたけど、
これは美しい!