関数ポインタに対応した make_overload を書いてみた
書いてみた。
C++11 でも動作するはず。
[ソース]
#include <functional> template<typename ...Args> struct overload; template<typename T> struct overload<T> : T{ using T::operator(); template<typename TT> overload(TT t) : T(t){} }; template<typename T, typename U, typename ...Args> struct overload<T, U, Args...> : T , overload<U, Args...>{ using T::operator(); using overload<U, Args...>::operator (); template<typename TT, typename... TArgs> overload(TT&& t, TArgs&&... args) : T(t) , overload<U, Args...>(args...){} }; template<typename Result, typename... Args> std::function<Result(Args...)> holder(Result(*func)(Args...), int){ return { func }; } template<typename F> F holder(F func, bool){ return func; } template<typename... F> overload<F...> make_overload_impl(F... fs){ return { fs... }; } template<typename... F> auto make_overload(F... fs) ->decltype(make_overload_impl(holder(fs, 0)...)){ return make_overload_impl(holder(fs, 0)...); } #include <iostream> #include <string> int plus(int a, int b){ return a + b; } int main(){ int n = 3; auto f = make_overload( [](std::string const& str){ return str + str; }, [&](int m){ return m + n; }, plus ); std::cout << f("homu") << std::endl; std::cout << f(5) << std::endl; std::cout << f(3, 8) << std::endl; return 0; }
[出力]
homuhomu 8 11
単純に関数ポインタ型の場合は std::function でラップしているだけ。
上のコードでもそこまで複雑ではないんだけど、もうちょいスマートに書けそうな気もする。