C++14 の Generic lambdas で SFINAE その 2
昨日書いたコードはあまり意味がなかったので簡単なラッパーを書いてラムダ式を多重定義で呼び出せるようにしてみました。
これなら SFINAE を使う意味も出てくるかな。
[ソース]
#include <iostream> #include <string> template<typename F1, typename F2> struct overload_impl : F1, F2{ using F1::operator(); using F2::operator(); overload_impl(F1 const& f1, F2 const& f2) : F1(f1), F2(f2){} }; template<typename F1, typename F2> overload_impl< typename std::decay<F1>::type, typename std::decay<F2>::type > overload(F1&& f1, F2&& f2){ return {f1, f2}; } int main(){ auto twice = overload( [](auto x) ->typename std::enable_if< std::is_integral<decltype(x)>{}, decltype(x) >::type{ std::cout << x << " << 1" << std::endl; return x << 1; }, [](auto x) ->typename std::enable_if< !std::is_integral<decltype(x)>{}, decltype(x) >::type{ std::cout << x << " + " << x << std::endl; return x + x; } ); std::cout << twice(10) << std::endl; std::cout << twice('!') << std::endl; std::cout << twice(3.14f) << std::endl; std::cout << twice(std::string("homu")) << std::endl; auto plus = overload( [](auto a, auto b) ->decltype(a + b){ return a + b; }, [](char const* str, auto b) ->decltype(std::string(str) + b){ return std::string(str) + b; } ); std::cout << plus(1, 2) << std::endl; std::cout << plus(2.5, 0.125) << std::endl; std::cout << plus(2.5, 5) << std::endl; std::cout << plus("homu", "mami") << std::endl; std::cout << plus("homu", std::string("mado")) << std::endl; // error // std::cout << plus(3.14f, "homu") << std::endl; return 0; }