#include <functional>
#include <iostream>
#include <cassert>
int foo(double d) { return d; }
double bar(double d) { return 2*d; }
struct Result {
union {
int i_res;
double d_res;
};
enum { IS_INT, IS_DOUBLE } u_tag;
Result(Result const&) = default;
Result(int i) : i_res{i}, u_tag{IS_INT} {}
Result(double d) : d_res{d}, u_tag{IS_DOUBLE} {}
Result& operator=(Result const&) = default;
auto& operator=(int i)
{ i_res = i; u_tag = IS_INT; return *this; }
auto& operator=(double d)
{ d_res = d; u_tag = IS_DOUBLE; return *this; }
};
int main() {
std::function<Result(double)> cb;
cb = foo;
auto r = cb(1.0);
assert(r.u_tag == Result::IS_INT);
std::cout << r.i_res << '\n';
cb = bar;
r = cb(2.0);
assert(r.u_tag == Result::IS_DOUBLE);
std::cout << r.d_res << '\n';
return 0;
}
I2luY2x1ZGUgPGZ1bmN0aW9uYWw+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPGNhc3NlcnQ+CgppbnQgICAgZm9vKGRvdWJsZSBkKSB7IHJldHVybiBkOyB9Cgpkb3VibGUgYmFyKGRvdWJsZSBkKSB7IHJldHVybiAyKmQ7IH0KCnN0cnVjdCBSZXN1bHQgewoJdW5pb24gewoJCWludCAgICBpX3JlczsKCQlkb3VibGUgZF9yZXM7Cgl9OwoJZW51bSB7IElTX0lOVCwgSVNfRE9VQkxFIH0gdV90YWc7CgkKCVJlc3VsdChSZXN1bHQgY29uc3QmKSA9IGRlZmF1bHQ7CglSZXN1bHQoaW50IGkpICA6IGlfcmVze2l9LCB1X3RhZ3tJU19JTlR9IHt9CglSZXN1bHQoZG91YmxlIGQpIDogZF9yZXN7ZH0sIHVfdGFne0lTX0RPVUJMRX0ge30KCQoJUmVzdWx0JiBvcGVyYXRvcj0oUmVzdWx0IGNvbnN0JikgPSBkZWZhdWx0OwoJYXV0byYgb3BlcmF0b3I9KGludCBpKQoJeyBpX3JlcyA9IGk7IHVfdGFnID0gSVNfSU5UOyAgICByZXR1cm4gKnRoaXM7IH0KCWF1dG8mIG9wZXJhdG9yPShkb3VibGUgZCkKCXsgZF9yZXMgPSBkOyB1X3RhZyA9IElTX0RPVUJMRTsgcmV0dXJuICp0aGlzOyB9Cn07CgppbnQgbWFpbigpIHsKCXN0ZDo6ZnVuY3Rpb248UmVzdWx0KGRvdWJsZSk+IGNiOwoJCgljYiA9IGZvbzsKCWF1dG8gciA9IGNiKDEuMCk7Cglhc3NlcnQoci51X3RhZyA9PSBSZXN1bHQ6OklTX0lOVCk7CglzdGQ6OmNvdXQgPDwgci5pX3JlcyA8PCAnXG4nOwoJCgljYiA9IGJhcjsKCXIgPSBjYigyLjApOwoJYXNzZXJ0KHIudV90YWcgPT0gUmVzdWx0OjpJU19ET1VCTEUpOyAKCXN0ZDo6Y291dCA8PCByLmRfcmVzIDw8ICdcbic7CgoJcmV0dXJuIDA7Cn0=