#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"; }
};
class foo {
public:
void foo1(int x, int y)
{
dispatch(&fooA::foo1, &fooB::foo1, &fooC::foo1, x, y);
}
void foo2(int x, double y, void *z)
{
dispatch(&fooA::foo2, &fooB::foo2, &fooC::foo2, x, y, z);
}
private:
template <typename... Args>
void dispatch(int (fooA::* f)(Args...),
void (fooB::* g)(Args...),
void (fooC::*h)(Args...),
Args... args)
{
switch((m_Member.*f)(args...)) {
case 1: (m_Member1.*g)(args...); return;
case 2: (m_Member2.*h)(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;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKICAgIHN0cnVjdCBmb29BIHsKICAgIAlpbnQgZm9vMShpbnQgeCwgaW50IHkpIHsgcmV0dXJuIHggKyB5OyB9CiAgICAJaW50IGZvbzIoaW50IHgsIGRvdWJsZSB5LCB2b2lkKikgeyByZXR1cm4geCArIHk7IH0KCX07CiAgICBzdHJ1Y3QgZm9vQiB7CiAgICAJdm9pZCBmb28xKGludCB4LCBpbnQgeSkgeyBzdGQ6OmNvdXQgPDwgImZvb0IoIiA8PCB4IDw8ICIsICIgPDwgeSA8PCAiKVxuIjsgfQogICAgCXZvaWQgZm9vMihpbnQgeCwgZG91YmxlIHksIHZvaWQqIHopIHsgc3RkOjpjb3V0IDw8ICJmb29CKCIgPDwgeCA8PCAiLCAiIDw8IHkgPDwgIiwgIiA8PCB6IDw8ICIpXG4iOyB9CiAgICB9OwogICAgc3RydWN0IGZvb0MgewogICAgCXZvaWQgZm9vMShpbnQgeCwgaW50IHkpIHsgc3RkOjpjb3V0IDw8ICJmb29DKCIgPDwgeCA8PCAiLCAiIDw8IHkgPDwgIilcbiI7IH0KICAgIAl2b2lkIGZvbzIoaW50IHgsIGRvdWJsZSB5LCB2b2lkKiB6KSB7IHN0ZDo6Y291dCA8PCAiZm9vQygiIDw8IHggPDwgIiwgIiA8PCB5IDw8ICIsICIgPDwgeiA8PCAiKVxuIjsgfQogICAgfTsKICAgIAogICAgY2xhc3MgZm9vIHsKICAgIHB1YmxpYzoKICAgICAgICB2b2lkIGZvbzEoaW50IHgsIGludCB5KQogICAgICAgIHsKICAgICAgICAgICAgZGlzcGF0Y2goJmZvb0E6OmZvbzEsICZmb29COjpmb28xLCAmZm9vQzo6Zm9vMSwgeCwgeSk7CiAgICAgICAgfQogICAgICAgIHZvaWQgZm9vMihpbnQgeCwgZG91YmxlIHksIHZvaWQgKnopCiAgICAgICAgewogICAgICAgICAgICBkaXNwYXRjaCgmZm9vQTo6Zm9vMiwgJmZvb0I6OmZvbzIsICZmb29DOjpmb28yLCB4LCB5LCB6KTsKICAgICAgICB9CgogICAgcHJpdmF0ZToKICAgICAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUuLi4gQXJncz4KICAgICAgICB2b2lkIGRpc3BhdGNoKGludCAoZm9vQTo6KiBmKShBcmdzLi4uKSwKICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKGZvb0I6OiogZykoQXJncy4uLiksCiAgICAgICAgICAgICAgICAgICAgICB2b2lkIChmb29DOjoqaCkoQXJncy4uLiksCiAgICAgICAgICAgICAgICAgICAgICBBcmdzLi4uIGFyZ3MpCiAgICAgICAgewogICAgICAgICAgIHN3aXRjaCgobV9NZW1iZXIuKmYpKGFyZ3MuLi4pKSB7CiAgICAgICAgICAgY2FzZSAxOiAobV9NZW1iZXIxLipnKShhcmdzLi4uKTsgcmV0dXJuOwogICAgICAgICAgIGNhc2UgMjogKG1fTWVtYmVyMi4qaCkoYXJncy4uLik7IHJldHVybjsKICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmb29BIG1fTWVtYmVyOwogICAgICAgIGZvb0IgbV9NZW1iZXIxOwogICAgICAgIGZvb0MgbV9NZW1iZXIyOwogICAgfTsKCmludCBtYWluKCkgewoJZm9vIGRpc3BhdGNoZXI7CglkaXNwYXRjaGVyLmZvbzEoMSwgMCk7CglkaXNwYXRjaGVyLmZvbzIoMSwgMSwgMCk7CglyZXR1cm4gMDsKfQ==