Boost.Lambdaでletとかwhereを書かせろ
#define LET(var) [&] { var IN #define IN(body) return body; }() #define LAMBDA(def) [&] { LAMBDA_WHERE(LAMBDA_WHERE_I def) return LAMBDA_BODY def )); }() #define LAMBDA_WHERE_I(body) LAMBDA_WHERE_II #define LAMBDA_WHERE_II(where) NIL where #define LAMBDA_WHERE(where) LAMBDA_WHERE_III(where) #define LAMBDA_WHERE_III(where) LAMBDA_WHERE_IV_ ## where #define LAMBDA_WHERE_IV_LAMBDA_WHERE_II #define LAMBDA_WHERE_IV_NIL #define LAMBDA_BODY(body) body LAMBDA_BODY_I(( #define LAMBDA_BODY_I(par) // let風 LET (int x = f(1, 2, 3);) (_1 + x) // where風 LAMBDA((_1 + x)(int x = f(1, 2, 3);)) LAMBDA((_1 + 1))
展開結果:http://codepad.org/C3kVMzVi
C++0xのラムダ式を多相型にしようとしても無理だったので、Boost.Lambdaでletとか使えればいいんじゃないかと思った。試すのは面倒なのでやってない。BOOST_PP_SEQ使えば楽ちんだけど修行した。名前を宣言するためだけにラムダ式で覆う。letとかwhereにあたる節をベタな式じゃなくて、名前、値、型(省略可)の何らかのデータ構造取るようにするとかもまたよいのではないかと。
追記:where風の実装がどうも気に入らないのでBoost.PPで書いてみた。しかしまだ気にいらない。
#include <boost/preprocessor/seq/elem.hpp> #include <boost/preprocessor/seq/size.hpp> #include <boost/preprocessor/arithmetic/dec.hpp> #include <boost/preprocessor/control/expr_iif.hpp> #define LAMBDA(seq) [&] { BOOST_PP_EXPR_IIF(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(seq)), BOOST_PP_SEQ_ELEM(1, seq)) return BOOST_PP_SEQ_ELEM(0, seq); }() // where風 LAMBDA((_1 + x)(int x = f(1, 2, 3);)) LAMBDA((_1 + 1))