不動点コンビネータで C++14 の Generic Lambdas をつかってみた

せっかくなので書いてみました。

[ソース]

#include <iostream>


// base code : http://d.hatena.ne.jp/iorate/20110729/1311949434
template<typename F>
struct fix_result{
    F f;

    template<typename ...Args>
    constexpr auto operator()(Args&&... args) const{
        return f(*this, std::forward<Args>(args)...);
    }
};


template<typename F>
fix_result<typename std::decay<F>::type>
fix(F&& f){
    return { std::forward<F>(f) };
}


int
main(){
    
    auto fact = [](auto f, auto n)
        // 戻り値型を明示しないとコンパイラがエラーはいた
        -> decltype(n){
        return n == 0 ? 1 : n * f(n - 1);
    };
    
    auto f_fact = fix(fact);
    std::cout << f_fact(5) << std::endl;

    std::cout << fix([](auto f, auto n)->decltype(n){
        return n <= 0 ? 1 : n + f(n - 1);
    })(100) << std::endl;

    return 0;
}

[出力]

120
5051


ラムダの戻り値型を明示的に記述しないとエラーになったのはコンパイラ側のバグかな。
ラムダもそうだけど関数の戻り値型の型推論もだいぶ強力。


[コンパイラ]

  • clang++ (LLVM) 3.4 20131004(trunk)