C++ のラムダ式の引数型を推論する

そういう話が Slack の C++ の会で出てたので簡単にラムダ式の引数型を取得するメタ関数を書いてみた。

#include <utility>

template<typename... Args>
struct parameter_pack{};

template<typename F, typename R, typename... Args>
parameter_pack<Args...>
args_impl(F, R(F::*f)(Args...) const);

template<typename F>
auto
args(F f)->decltype(args_impl(f, &F::operator()));


int
main(){
    auto f = [](int){};
    static_assert(std::is_same<decltype(args(f)), parameter_pack<int>>{}, "");

    auto f2 = [](float, int, double){};
    static_assert(std::is_same<decltype(args(f2)), parameter_pack<float, int, double>>{}, "");

    return 0;
}

::operator() から引数型を推論しています。
同様に戻り値型もこれで推論することができます。