#include <iostream>
struct fooA {
int foo1(int x, int y) { return x + y; }
int foo2(int x, double y, void *) { return x + y; }
};
struct fooB {
void foo1(int x, int y) { std::cout << "fooB(" << x << ", " << y << ")\n"; }
void foo2(int x, double y, void *z) { std::cout << "fooB(" << x << ", " << y << ", " << z << ")\n"; }
};
struct fooC {
void foo1(int x, int y) { std::cout << "fooC(" << x << ", " << y << ")\n"; }
void foo2(int x, double y, void *z) { std::cout << "fooC(" << x << ", " << y << ", " << z << ")\n"; }
};
#define Return(ret) decltype ret { return ret; }
struct foo1Caller
{
template <typename T, typename... Args>
auto operator () (T& t, Args... args) -> Return((t.foo1(args...)))
};
struct foo2Caller
{
template <typename T, typename... Args>
auto operator () (T& t, Args... args) -> Return((t.foo2(args...)))
};
class foo
{
public:
void foo1(int x, int y)
{
dispatch(foo1Caller(), x, y);
}
void foo2(int x, double y, void *z)
{
dispatch(foo2Caller(), x, y, z);
}
private:
template <typename T, typename... Args>
void dispatch(T caller, Args... args)
{
switch (caller(m_Member, args...)) {
case 1: caller(m_Member1, args...); return;
case 2: caller(m_Member2, args...); return;
}
}
fooA m_Member;
fooB m_Member1;
fooC m_Member2;
};
int main()
{
foo dispatcher;
dispatcher.foo1(1, 0);
dispatcher.foo2(1, 1, 0);
return 0;
}
CiNpbmNsdWRlIDxpb3N0cmVhbT4KCnN0cnVjdCBmb29BIHsKICAgIGludCBmb28xKGludCB4LCBpbnQgeSkgeyByZXR1cm4geCArIHk7IH0KICAgIGludCBmb28yKGludCB4LCBkb3VibGUgeSwgdm9pZCAqKSB7IHJldHVybiB4ICsgeTsgfQp9OwpzdHJ1Y3QgZm9vQiB7CiAgICB2b2lkIGZvbzEoaW50IHgsIGludCB5KSB7IHN0ZDo6Y291dCA8PCAiZm9vQigiIDw8IHggPDwgIiwgIiA8PCB5IDw8ICIpXG4iOyB9CiAgICB2b2lkIGZvbzIoaW50IHgsIGRvdWJsZSB5LCB2b2lkICp6KSB7IHN0ZDo6Y291dCA8PCAiZm9vQigiIDw8IHggPDwgIiwgIiA8PCB5IDw8ICIsICIgPDwgeiA8PCAiKVxuIjsgfQp9OwpzdHJ1Y3QgZm9vQyB7CiAgICB2b2lkIGZvbzEoaW50IHgsIGludCB5KSB7IHN0ZDo6Y291dCA8PCAiZm9vQygiIDw8IHggPDwgIiwgIiA8PCB5IDw8ICIpXG4iOyB9CiAgICB2b2lkIGZvbzIoaW50IHgsIGRvdWJsZSB5LCB2b2lkICp6KSB7IHN0ZDo6Y291dCA8PCAiZm9vQygiIDw8IHggPDwgIiwgIiA8PCB5IDw8ICIsICIgPDwgeiA8PCAiKVxuIjsgfQp9OwoKI2RlZmluZSBSZXR1cm4ocmV0KSBkZWNsdHlwZSByZXQgeyByZXR1cm4gcmV0OyB9CgpzdHJ1Y3QgZm9vMUNhbGxlcgp7CiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUuLi4gQXJncz4KICAgIGF1dG8gb3BlcmF0b3IgKCkgKFQmIHQsIEFyZ3MuLi4gYXJncykgLT4gUmV0dXJuKCh0LmZvbzEoYXJncy4uLikpKQp9OwoKc3RydWN0IGZvbzJDYWxsZXIKewogICAgdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lLi4uIEFyZ3M+CiAgICBhdXRvIG9wZXJhdG9yICgpIChUJiB0LCBBcmdzLi4uIGFyZ3MpIC0+IFJldHVybigodC5mb28yKGFyZ3MuLi4pKSkKfTsKCgpjbGFzcyBmb28KewpwdWJsaWM6CiAgICB2b2lkIGZvbzEoaW50IHgsIGludCB5KQogICAgewogICAgICAgIGRpc3BhdGNoKGZvbzFDYWxsZXIoKSwgeCwgeSk7CiAgICB9CiAgICB2b2lkIGZvbzIoaW50IHgsIGRvdWJsZSB5LCB2b2lkICp6KQogICAgewogICAgICAgIGRpc3BhdGNoKGZvbzJDYWxsZXIoKSwgeCwgeSwgeik7CiAgICB9Cgpwcml2YXRlOgogICAgdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lLi4uIEFyZ3M+CiAgICB2b2lkIGRpc3BhdGNoKFQgY2FsbGVyLCBBcmdzLi4uIGFyZ3MpCiAgICB7CiAgICAgICAgc3dpdGNoIChjYWxsZXIobV9NZW1iZXIsIGFyZ3MuLi4pKSB7CiAgICAgICAgICAgIGNhc2UgMTogY2FsbGVyKG1fTWVtYmVyMSwgYXJncy4uLik7IHJldHVybjsKICAgICAgICAgICAgY2FzZSAyOiBjYWxsZXIobV9NZW1iZXIyLCBhcmdzLi4uKTsgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICBmb29BIG1fTWVtYmVyOwogICAgZm9vQiBtX01lbWJlcjE7CiAgICBmb29DIG1fTWVtYmVyMjsKfTsKCmludCBtYWluKCkKewogICAgZm9vIGRpc3BhdGNoZXI7CiAgICBkaXNwYXRjaGVyLmZvbzEoMSwgMCk7CiAgICBkaXNwYXRjaGVyLmZvbzIoMSwgMSwgMCk7CiAgICByZXR1cm4gMDsKfQo=