#include <iostream>
using namespace std;
template <typename ...Funcs>
struct overload_set;
template <typename Head, typename ...Tail>
struct overload_set<Head, Tail...> : Head, overload_set < Tail... >
{
overload_set(Head head, Tail... tail)
: Head(head)
, overload_set < Tail... > (tail...)
{}
using Head::operator();
using overload_set<Tail...>::operator();
};
template <typename Func>
struct overload_set<Func> : Func
{
overload_set(Func func)
: Func(func)
{}
using Func::operator();
};
template <typename ...Funcs>
overload_set<Funcs...> overload(Funcs... funcs)
{
return overload_set < Funcs... > (funcs...);
}
int main()
{
auto f = overload(
[] { return 1; }, // 1
[](int x) { return x + 1; }, // 2
[](double x) { return 2 * x; } // 3
);
using std::cout;
using std::endl;
cout << f() << endl // call 1
<< f(1) << endl // call 2
<< f(2.0) << endl; // call 3
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKdGVtcGxhdGUgPHR5cGVuYW1lIC4uLkZ1bmNzPgpzdHJ1Y3Qgb3ZlcmxvYWRfc2V0OwoKdGVtcGxhdGUgPHR5cGVuYW1lIEhlYWQsIHR5cGVuYW1lIC4uLlRhaWw+CnN0cnVjdCBvdmVybG9hZF9zZXQ8SGVhZCwgVGFpbC4uLj4gOiBIZWFkLCBvdmVybG9hZF9zZXQgPCBUYWlsLi4uID4KewoJb3ZlcmxvYWRfc2V0KEhlYWQgaGVhZCwgVGFpbC4uLiB0YWlsKQoJOiBIZWFkKGhlYWQpCgksIG92ZXJsb2FkX3NldCA8IFRhaWwuLi4gPiAodGFpbC4uLikKCXt9CgoJdXNpbmcgSGVhZDo6b3BlcmF0b3IoKTsKCXVzaW5nIG92ZXJsb2FkX3NldDxUYWlsLi4uPjo6b3BlcmF0b3IoKTsKfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBGdW5jPgpzdHJ1Y3Qgb3ZlcmxvYWRfc2V0PEZ1bmM+IDogRnVuYwp7CglvdmVybG9hZF9zZXQoRnVuYyBmdW5jKQoJOiBGdW5jKGZ1bmMpCgl7fQoKCXVzaW5nIEZ1bmM6Om9wZXJhdG9yKCk7Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgLi4uRnVuY3M+Cm92ZXJsb2FkX3NldDxGdW5jcy4uLj4gb3ZlcmxvYWQoRnVuY3MuLi4gZnVuY3MpCnsKCXJldHVybiBvdmVybG9hZF9zZXQgPCBGdW5jcy4uLiA+IChmdW5jcy4uLik7Cn0KCmludCBtYWluKCkKewoJYXV0byBmID0gb3ZlcmxvYWQoCgkJW10geyByZXR1cm4gMTsgfSwgICAgICAgICAgICAgICAgLy8gMQoJCVtdKGludCB4KSB7IHJldHVybiB4ICsgMTsgfSwgICAgLy8gMgoJCVtdKGRvdWJsZSB4KSB7IHJldHVybiAyICogeDsgfSAgLy8gMwoJKTsKCgl1c2luZyBzdGQ6OmNvdXQ7Cgl1c2luZyBzdGQ6OmVuZGw7Cgljb3V0IDw8IGYoKSA8PCBlbmRsICAgICAgICAgLy8gY2FsbCAxCgkJPDwgZigxKSA8PCBlbmRsICAgICAgICAvLyBjYWxsIDIKCQk8PCBmKDIuMCkgPDwgZW5kbDsgICAgIC8vIGNhbGwgMwoKCXJldHVybiAwOwp9