#include <iostream>
#include <unordered_map>
#include <string>
using namespace std;
class Server {
private:
using erasedType = void (*)();
unordered_map<string, erasedType> funcs;
public:
template<typename... Args>
void Register(const string& name, void (*func)(Args...)) {
funcs[name] = reinterpret_cast<erasedType>(func);
}
template<typename... Args>
void Call(const string& name, Args... args) {
using funcType = void (*)(Args...);
auto func = reinterpret_cast<funcType>(funcs.at(name));
return func(args...);
}
};
int main() {
Server server;
server.Register("Add", +[](int a, int b){ cout << a+b << endl; });
server.Register("Echo", +[](string str){ cout << str << endl; });
server.Call("Add", 12, 13);
server.Call("Echo", string("hello"));
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dW5vcmRlcmVkX21hcD4KI2luY2x1ZGUgPHN0cmluZz4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCmNsYXNzIFNlcnZlciB7CnByaXZhdGU6Cgl1c2luZyBlcmFzZWRUeXBlID0gdm9pZCAoKikoKTsKCXVub3JkZXJlZF9tYXA8c3RyaW5nLCBlcmFzZWRUeXBlPiBmdW5jczsKcHVibGljOgoJdGVtcGxhdGU8dHlwZW5hbWUuLi4gQXJncz4KCXZvaWQgUmVnaXN0ZXIoY29uc3Qgc3RyaW5nJiBuYW1lLCB2b2lkICgqZnVuYykoQXJncy4uLikpIHsKCQlmdW5jc1tuYW1lXSA9IHJlaW50ZXJwcmV0X2Nhc3Q8ZXJhc2VkVHlwZT4oZnVuYyk7Cgl9CgkKCXRlbXBsYXRlPHR5cGVuYW1lLi4uIEFyZ3M+Cgl2b2lkIENhbGwoY29uc3Qgc3RyaW5nJiBuYW1lLCBBcmdzLi4uIGFyZ3MpIHsKCQl1c2luZyBmdW5jVHlwZSA9IHZvaWQgKCopKEFyZ3MuLi4pOwoJCWF1dG8gZnVuYyA9IHJlaW50ZXJwcmV0X2Nhc3Q8ZnVuY1R5cGU+KGZ1bmNzLmF0KG5hbWUpKTsKCQlyZXR1cm4gZnVuYyhhcmdzLi4uKTsKCX0KfTsKCmludCBtYWluKCkgewoJU2VydmVyIHNlcnZlcjsKCXNlcnZlci5SZWdpc3RlcigiQWRkIiwgK1tdKGludCBhLCBpbnQgYil7IGNvdXQgPDwgYStiIDw8IGVuZGw7IH0pOwoJc2VydmVyLlJlZ2lzdGVyKCJFY2hvIiwgK1tdKHN0cmluZyBzdHIpeyBjb3V0IDw8IHN0ciA8PCBlbmRsOyB9KTsKCQogICAgc2VydmVyLkNhbGwoIkFkZCIsIDEyLCAxMyk7CiAgICBzZXJ2ZXIuQ2FsbCgiRWNobyIsIHN0cmluZygiaGVsbG8iKSk7CgoJcmV0dXJuIDA7Cn0=