パスワードを忘れた? アカウント作成
90008 journal

eldeshの日記: foldl改良

日記 by eldesh
前回のfoldlを改良した.
これを使って二項演算のAddからリストの要素を全て合計するSumを定義できた :D
gccの制限(多分)で特殊化が必要になってるけど,
かなり'関数'っぽくなってきたのでは無かろうか.

前回からvariadic templateがやたらマッチング規則(?)が緩いなーと思って使ってたけど,
いろんな引数のものが定義できるのは,
特殊化と言うよりオーバーロードっぽい気がした.かなり強力.
なんとなく書けちゃうかんじ.(gccを信用すればだけど.)

ところでfoldlを書いてる時に, UとT0は同じで, TとHDは同じ種類の型と言うことが表したくなった.
だけどここで扱ってるのは既に型なので,
通常のMLみたいに型注釈が記述できない!><

// foldl
template< template< class T, class U > class F, typename T0, typename HD, typename ...TL >
struct foldl {
    typedef typename foldl< F,
            typename F<HD, T0>::type,
            tuple<TL...>
        >::type type;
};

template< template< class T, class U > class F, typename T0, typename HD, typename ...TL >
struct foldl<F, T0, tuple<HD,TL...>> {
    typedef typename foldl< F,
            typename F<HD, T0>::type,
            tuple<TL...>
        >::type type;
};

// foldlの終端
template< template< class T, class U > class F, typename T0 >
struct foldl<F, T0, tuple<>> {
    typedef T0 type;
};

// 整数
template< int N >
struct Int {
    enum { value = N };
};

// Arity2の加算
template< typename X, typename Y >
struct Add {
    typedef Int<X::value+Y::value> type;
    enum { value = X::value + Y::value };
};

// リストの要素を合計する
template< typename ...Seq >
struct Sum {
    typedef
      typename foldl<
              Add, Int<0>, tuple<Seq...>
        >::type type;
};

// Sumの終端の特殊化
template<>
struct Sum<tuple<>> {
    typedef
          foldl<
              Add, Int<0>, tuple<>
        >::type type;
};

int main(){

    int p;
    // foldl改良版テスト
    name = typeid(
            foldl<
                Add, Int<0>,
                Int<1>, Int<2>, Int<3>, Int<4>, Int<5>
            >::type
        ).name();
    cout << abi::__cxa_demangle(name.c_str(), 0, 0, &p) << endl;

    // Sumテスト
    name = typeid(
            Sum<
                Int<1>, Int<2>, Int<3>, Int<4>, Int<5>
            >::type
        ).name();
    cout << abi::__cxa_demangle(name.c_str(), 0, 0, &p) << endl;

    return 0;
}

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
typodupeerror

開いた括弧は必ず閉じる -- あるプログラマー

読み込み中...