『C++テンプレートテクニック』もうすぐ発売です。

私とεπιστημηさんの2人で、C++テンプレート本書きました。
(ぼくは著者名を本名で載せてます)

発売日は2009/04/24(金)で、税込2,940円になります。


内容は、テンプレートの基礎から始まり、テンプレートメタプログラミング
Boost C++ Librariesの中で使われている手法、C++0xでテンプレートがどのように進化していくか等を紹介しています。


本屋とかAmazonで見かけたら買ってやってください。



可変引数テンプレートでの型リスト - filter

filterは型リストから条件にあった型を抽出するメタ関数です。
mapと同じく高階メタ関数になってます。

template <template <class T> class P, class Seq1, class Seq2>
struct filter_impl;

template <template <class T> class P, class... Seq, class Head, class... Tail>
struct filter_impl<P, tuple<Seq...>, tuple<Head, Tail...>> {
    typedef
        typename filter_impl<P,
                             typename add_if<P,
                                             Head,
                                             tuple<Seq...>>::type,
                             tuple<Tail...>>::type
    type;
};

template <template <class T> class P, class... Seq>
struct filter_impl<P, tuple<Seq...>, tuple<>> {
    typedef tuple<Seq...> type;
};


template <template <class T> class P, class... Seq>
struct filter;

template <template <class T> class P, class... Seq>
struct filter<P, tuple<Seq...>> {
    typedef typename filter_impl<P, tuple<>, tuple<Seq...>>::type type;
};
filter<is_integral, tuple<int, double, long>>::type
→ tuple<int, long>

filterの実装で使用しているadd_ifメタ関数はこれです。


可変引数テンプレートでの型リスト - add_if/add_if_c

filterの実装用メタ関数。


パラメータで受け取った述語(メタ関数)がtrueを返す場合に、
型リストに型を追加するメタ関数です。

template <bool B, class T, class Seq>
struct add_if_c;

template <class T, class... Seq>
struct add_if_c<true, T, tuple<Seq...>> {
    typedef tuple<Seq..., T> type;
};

template <class T, class... Seq>
struct add_if_c<false, T, tuple<Seq...>> {
    typedef tuple<Seq...> type;
};

template <template <class> class P, class T, class... Seq>
struct add_if;

template <template <class> class P, class T, class... Seq>
struct add_if<P, T, tuple<Seq...>> :
    public add_if_c<P<T>::value, T, tuple<Seq...>> {};
typedef add_if<is_integral, int, tuple<long, double>>::type type;
→ tuple<long, double, int>
typedef add_if<is_integral, double, tuple<long, double>>::type type;
→ tuple<long, double>


GCC 4.4でこれができなかった。

template <template <class> class P, class T, class... Seq>
struct add_if : public add_if_c<P<T>::value, T, Seq...> {}; // エラー!sorry not implement