#include <iostream>
struct A{
typedef void (*callback_type)(void*, int);
callback_type callback;
void* user_data;
void set_callback(callback_type cb, void* ud){
callback = cb; user_data = ud;
}
void invoke(){ callback(user_data, 42); }
};
struct B{
static void cb_foo(void* vself, int data){
B* self = static_cast<B*>(vself);
self->foo(data);
}
void foo(int data){ std::cout << data * 2 << "\n"; }
};
struct C{
static void cb_bar(void* vself, int data){
C* self = static_cast<C*>(vself);
self->bar(data);
}
void bar(int data){ std::cout << data / 2 << "\n"; }
};
int main(){
A a;
B b;
a.set_callback(&B::cb_foo, &b);
a.invoke();
C c;
a.set_callback(&C::cb_bar, &c);
a.invoke();
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKc3RydWN0IEF7CiAgdHlwZWRlZiB2b2lkICgqY2FsbGJhY2tfdHlwZSkodm9pZCosIGludCk7CiAgY2FsbGJhY2tfdHlwZSBjYWxsYmFjazsKICB2b2lkKiB1c2VyX2RhdGE7CiAgdm9pZCBzZXRfY2FsbGJhY2soY2FsbGJhY2tfdHlwZSBjYiwgdm9pZCogdWQpewogICAgIGNhbGxiYWNrID0gY2I7IHVzZXJfZGF0YSA9IHVkOwogIH0KICB2b2lkIGludm9rZSgpeyBjYWxsYmFjayh1c2VyX2RhdGEsIDQyKTsgfQp9OwoKc3RydWN0IEJ7CiAgc3RhdGljIHZvaWQgY2JfZm9vKHZvaWQqIHZzZWxmLCBpbnQgZGF0YSl7CiAgICBCKiBzZWxmID0gc3RhdGljX2Nhc3Q8Qio+KHZzZWxmKTsKICAgIHNlbGYtPmZvbyhkYXRhKTsKICB9CiAgdm9pZCBmb28oaW50IGRhdGEpeyBzdGQ6OmNvdXQgPDwgZGF0YSAqIDIgPDwgIlxuIjsgfQp9OwoKc3RydWN0IEN7CiAgc3RhdGljIHZvaWQgY2JfYmFyKHZvaWQqIHZzZWxmLCBpbnQgZGF0YSl7CiAgICBDKiBzZWxmID0gc3RhdGljX2Nhc3Q8Qyo+KHZzZWxmKTsKICAgIHNlbGYtPmJhcihkYXRhKTsKICB9CiAgdm9pZCBiYXIoaW50IGRhdGEpeyBzdGQ6OmNvdXQgPDwgZGF0YSAvIDIgPDwgIlxuIjsgfQp9OwoKaW50IG1haW4oKXsKICBBIGE7CiAgQiBiOwogIGEuc2V0X2NhbGxiYWNrKCZCOjpjYl9mb28sICZiKTsKICBhLmludm9rZSgpOwogIEMgYzsKICBhLnNldF9jYWxsYmFjaygmQzo6Y2JfYmFyLCAmYyk7CiAgYS5pbnZva2UoKTsKfQo=