関数適用演算子
Haskell には関数適用演算子 $ があり、しばしば括弧を省く目的で用いられます。C++ でもやってみましょう。
#include <utility> namespace apply { template <class F, class A> inline auto operator|=(F &&f, A &&a) -> decltype(std::forward<F>(f)(std::forward<A>(a))) { return std::forward<F>(f)(std::forward<A>(a)); } } #include <iostream> int main() { auto const f = [](int x) { return x + 1; }; auto const g = [](int x) { return x * 2; }; using namespace apply; std::cout << (f |= g |= 3); // 7 }
= を使っているのは右結合だからです。 |
しかしこのアプローチでは、オペランドが共に非クラス型 (関数と整数など) である場合に対応できません。この点を解決し、さらに Boost.Lambda のサポートを追加したものがこちらになります。
https://gist.github.com/948021
使い方
#include <iostream> #include <boost/lambda/lambda.hpp> #include "apply.hpp" int f(int x) { return x + 1; } int g(int x) { return x * 2; } int main() { using namespace boost::lambda; using namespace apply; std::cout << ( // f $ g $ 3 f |=S|= g |=S|= 3 ) << "\n"; std::cout << ( // (\x -> f $ x $ 3) g (f |=S|= _1 |=S|= 3)(g) ) << "\n"; }
=S | = は $ または $! を表したものです。心の目で見てください。 |
最初のものに比べて、引数が rvalue の場合の効率は落ちますが、より広い範囲で使えるようになっています。
…やっぱり無理がありますね