#include <iostream>
struct CallIntDelegate
{
virtual void operator()(int i) const = 0;
};
template<typename O, void (O::*func)(int)>
struct IntCaller : public CallIntDelegate
{
IntCaller(O* obj) : object(obj) {}
void operator()(int i) const
{
// This line can easily optimized by the compiler
// in object->func(i) (= normal function call, not pointer-to-member call)
// Pointer-to-member calls are slower than regular function calls
(object->*func)(i);
}
private:
O* object;
};
void set(const CallIntDelegate& setValue)
{
setValue(42);
}
class test
{
public:
void printAnswer(int i)
{
std::cout << "The answer is " << 2 * i << "\n";
}
};
int main()
{
test obj;
set(IntCaller<test,&test::printAnswer>(&obj));
}
ICAgICNpbmNsdWRlIDxpb3N0cmVhbT4KICAgIHN0cnVjdCBDYWxsSW50RGVsZWdhdGUKICAgIHsKICAgICAgICB2aXJ0dWFsIHZvaWQgb3BlcmF0b3IoKShpbnQgaSkgY29uc3QgPSAwOwogICAgfTsKCiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBPLCB2b2lkIChPOjoqZnVuYykoaW50KT4KICAgIHN0cnVjdCBJbnRDYWxsZXIgOiBwdWJsaWMgQ2FsbEludERlbGVnYXRlCiAgICB7CiAgICAgICAgSW50Q2FsbGVyKE8qIG9iaikgOiBvYmplY3Qob2JqKSB7fQogICAgICAgIHZvaWQgb3BlcmF0b3IoKShpbnQgaSkgY29uc3QKICAgICAgICB7CiAgICAgICAgICAgIC8vIFRoaXMgbGluZSBjYW4gZWFzaWx5IG9wdGltaXplZCBieSB0aGUgY29tcGlsZXIKICAgICAgICAgICAgLy8gaW4gb2JqZWN0LT5mdW5jKGkpICg9IG5vcm1hbCBmdW5jdGlvbiBjYWxsLCBub3QgcG9pbnRlci10by1tZW1iZXIgY2FsbCkKICAgICAgICAgICAgLy8gUG9pbnRlci10by1tZW1iZXIgY2FsbHMgYXJlIHNsb3dlciB0aGFuIHJlZ3VsYXIgZnVuY3Rpb24gY2FsbHMKICAgICAgICAgICAgKG9iamVjdC0+KmZ1bmMpKGkpOwogICAgICAgIH0KICAgIHByaXZhdGU6CiAgICAgICAgTyogb2JqZWN0OwogICAgfTsKCiAgICB2b2lkIHNldChjb25zdCBDYWxsSW50RGVsZWdhdGUmIHNldFZhbHVlKQogICAgewogICAgICAgIHNldFZhbHVlKDQyKTsKICAgIH0KCiAgICBjbGFzcyB0ZXN0CiAgICB7CiAgICBwdWJsaWM6CiAgICAgICAgdm9pZCBwcmludEFuc3dlcihpbnQgaSkKICAgICAgICB7CiAgICAgICAgICAgIHN0ZDo6Y291dCA8PCAiVGhlIGFuc3dlciBpcyAiIDw8IDIgKiBpIDw8ICJcbiI7CiAgICAgICAgfQogICAgfTsKCiAgICBpbnQgbWFpbigpCiAgICB7CiAgICAgICAgdGVzdCBvYmo7CiAgICAgICAgc2V0KEludENhbGxlcjx0ZXN0LCZ0ZXN0OjpwcmludEFuc3dlcj4oJm9iaikpOwogICAgfQ==