How to implement a very simple edition of boost::bind, which does not bind arguments, but offer a way to call member function in c++ classes.
Here is my first try:
#include <iostream>
struct Foo {
void x(int i) { std::cout << "Foo " << i << std::endl; }
};
struct Bar {
void y(int i) { std::cout << "Bar " << i << std::endl; }
};
template<typename A1, typename I, typename M>
struct Binder {
Binder(I i, M m) : i_(i), m_(m) { }
void operator()(A1 a1) {
(i_->*m_)(a1);
}
I i_;
M m_;
};
template<typename A1, typename I, typename M>
Binder<A1, I, M> my_bind(I i, M m) {
return Binder<A1, I, M>(i, m);
}
int main(int argc, const char *argv[])
{
Foo foo;
Bar bar;
Binder<int, Foo*, void (Foo::*)(int)> b1 = my_bind<int>(&foo, &Foo::x);
Binder<int, Bar*, void (Bar::*)(int)> b2 = my_bind<int>(&bar, &Bar::y);
b1(1);
b2(2);
return 0;
}
The implementation above does work, and will print:
Foo 1
Bar 2
The problem is that the two invokes of my_bind returns objects of different types. How can I alter the program, such that my_bind will return a type which only depends on A1.
It is possible to do with type erasure.
In short:
live demo
Usage:
Full code:
P.S. If you are sure, that all your Concrete classes would have same size, then you can replace heap allocations with placement new inside to fixed size buffer, and add static_assert for safety.