// リンクの終端 struct Nil {}; // 左畳み込みテンプレート template<template<typename, typename> class Operator, typename N, typename Sequence> struct Foldl { static const int value = Foldl< Operator, Operator<N, typename Sequence::head>, typename Sequence::tail >::value; }; // 左畳み込みテンプレート(終端処理) template<template<typename, typename> class Operator, typename N> struct Foldl<Operator, N, Nil> { static const int value = N::value; }; // 以下、畳み込みの利用例 // 整数-型変換テンプレート template<int N> struct Int { static const int value = N; }; // N から 1 までのシーケンスを生成するテンプレート template<int N> struct DownToOne { typedef Int<N> head; typedef DownToOne<N - 1> tail; }; // N から 1 までのシーケンスを生成するテンプレート(終端) template<> struct DownToOne<1> { typedef Int<1> head; typedef Nil tail; }; // 加算演算子テンプレート template<typename T, typename U> struct Add { static const int value = T::value + U::value; }; // 10 から 1 までを初期値 0 から加算で左畳み込み( ((((((((((0 + 10) + 9) + 8) + 7) + 6) + 5) + 4) + 3) + 2) + 1) ) int n = Foldl<Add, Int<0>, DownToOne<10>>::value;
実行結果。
$ g++ --std=c++11 -S foldl.cpp $ cat foldl.s .section __TEXT,__text,regular,pure_instructions .section __DATA,__data .globl _n ## @n .align 2 _n: .long 55 ## 0x37
つづく。