#include <iostream>
#include <string>
#include <functional>
#include <memory>
class MyClass
{
float myFloat;
public:
MyClass(float f):myFloat(f){}
void myFunc(int arg1)
{
std::cout << arg1 << ", " << myFloat << '\n';
}
};
class MyContainer
{
public:
MyClass* object;
};
// DelayedCaller implementation
class DelayedCaller
{
public:
template <typename TFunction, typename... TArgs>
static std::shared_ptr<DelayedCaller> setup(TFunction&& a_func,
TArgs&&... a_args)
{
return std::shared_ptr<DelayedCaller>(new DelayedCaller(
std::bind(std::forward<TFunction>(a_func),
std::forward<TArgs>(a_args)...)));
}
void call() const { func_(); }
private:
using func_type = std::function<void()>;
DelayedCaller(func_type&& a_ft) : func_(std::forward<func_type>(a_ft)) {}
func_type func_;
};
int main()
{
MyContainer container;
MyClass c1(45.6);
container.object = &c1;
// the next line is the critical one. Instead of myFunc being called
// on the current value of container.object, it should be called on
// the one container.object is holding when caller is called.
auto caller(DelayedCaller::setup(&MyClass::myFunc, std::ref(container.object), 123));
caller->call();
MyClass c2(22.8);
container.object = &c2;
caller->call();
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KI2luY2x1ZGUgPG1lbW9yeT4KCmNsYXNzIE15Q2xhc3MKewogICAgZmxvYXQgbXlGbG9hdDsKcHVibGljOgogICAgTXlDbGFzcyhmbG9hdCBmKTpteUZsb2F0KGYpe30KCiAgICB2b2lkIG15RnVuYyhpbnQgYXJnMSkKICAgIHsKICAgICAgICBzdGQ6OmNvdXQgPDwgYXJnMSA8PCAiLCAiIDw8IG15RmxvYXQgPDwgJ1xuJzsKICAgIH0KfTsKCmNsYXNzIE15Q29udGFpbmVyCnsKcHVibGljOgogICAgTXlDbGFzcyogb2JqZWN0Owp9OwoKLy8gRGVsYXllZENhbGxlciBpbXBsZW1lbnRhdGlvbgpjbGFzcyBEZWxheWVkQ2FsbGVyCnsKcHVibGljOgogICAgdGVtcGxhdGUgPHR5cGVuYW1lIFRGdW5jdGlvbiwgdHlwZW5hbWUuLi4gVEFyZ3M+CiAgICBzdGF0aWMgc3RkOjpzaGFyZWRfcHRyPERlbGF5ZWRDYWxsZXI+IHNldHVwKFRGdW5jdGlvbiYmIGFfZnVuYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVEFyZ3MmJi4uLiBhX2FyZ3MpCiAgICB7CiAgICAgICAgcmV0dXJuIHN0ZDo6c2hhcmVkX3B0cjxEZWxheWVkQ2FsbGVyPihuZXcgRGVsYXllZENhbGxlcigKICAgICAgICAgICAgc3RkOjpiaW5kKHN0ZDo6Zm9yd2FyZDxURnVuY3Rpb24+KGFfZnVuYyksCiAgICAgICAgICAgICAgICAgICAgICBzdGQ6OmZvcndhcmQ8VEFyZ3M+KGFfYXJncykuLi4pKSk7CiAgICB9CiAgICB2b2lkIGNhbGwoKSBjb25zdCB7IGZ1bmNfKCk7IH0KCnByaXZhdGU6CiAgICB1c2luZyBmdW5jX3R5cGUgPSBzdGQ6OmZ1bmN0aW9uPHZvaWQoKT47CiAgICBEZWxheWVkQ2FsbGVyKGZ1bmNfdHlwZSYmIGFfZnQpIDogZnVuY18oc3RkOjpmb3J3YXJkPGZ1bmNfdHlwZT4oYV9mdCkpIHt9CiAgICBmdW5jX3R5cGUgZnVuY187Cn07CgppbnQgbWFpbigpCnsKICAgIE15Q29udGFpbmVyIGNvbnRhaW5lcjsKICAgIE15Q2xhc3MgYzEoNDUuNik7CiAgICBjb250YWluZXIub2JqZWN0ID0gJmMxOwogICAgLy8gdGhlIG5leHQgbGluZSBpcyB0aGUgY3JpdGljYWwgb25lLiBJbnN0ZWFkIG9mIG15RnVuYyBiZWluZyBjYWxsZWQKICAgIC8vIG9uIHRoZSBjdXJyZW50IHZhbHVlIG9mIGNvbnRhaW5lci5vYmplY3QsIGl0IHNob3VsZCBiZSBjYWxsZWQgb24KICAgIC8vIHRoZSBvbmUgY29udGFpbmVyLm9iamVjdCBpcyBob2xkaW5nIHdoZW4gY2FsbGVyIGlzIGNhbGxlZC4KICAgIGF1dG8gY2FsbGVyKERlbGF5ZWRDYWxsZXI6OnNldHVwKCZNeUNsYXNzOjpteUZ1bmMsIHN0ZDo6cmVmKGNvbnRhaW5lci5vYmplY3QpLCAxMjMpKTsKCiAgICBjYWxsZXItPmNhbGwoKTsKCiAgICBNeUNsYXNzIGMyKDIyLjgpOwogICAgY29udGFpbmVyLm9iamVjdCA9ICZjMjsKICAgIGNhbGxlci0+Y2FsbCgpOwp9