Say I have these 3 different functions that I may want to point to:
float test1(int a, int b) {
return 7.0f;
}
struct TestClass {
float test2(int a, int b) {
return 5.0f;
}
};
struct TestClass2 {
float test3(int a, int b) {
return 3.0f;
}
};
Notice how all three use the same arguments and return value. I want to abstract away whether or not it is a member function and which class it belonged to. I want a delegate type that could be referring to any of these 3 functions depending only on how it was initialized.
Here is my first attempt:
typedef std::function<float(int, int)> MyDelegate; // is this right?
int main() {
TestClass obj;
TestClass2 obj2;
MyDelegate a = test1;
MyDelegate b = std::bind(std::mem_fn(&TestClass::test2), obj); // is this right?
MyDelegate c = std::bind(std::mem_fn(&TestClass2::test3), obj2); // is this right?
return 0;
}
The idea is I want to also store the 'this' pointer inside the wrapper too. This way, it's like a fully functional delegate.For example, invoking 'b(x, y)' should be like calling obj.test2(x, y)
.
I just can't even make it compile, I'm probably not fully grasping this. I'm kind of new to these libraries and the errors in VS2012 are catastrophically unhelpful. Any help would be appreciated.
You need to tell std::bind
what to do with the other function parameters. In order to make the call b(x, y)
delegate x
and y
to the two original function parameters you need to use placeholders from the std::placeholders
namespace:
std::bind(&TestClass::test2, obj, std::placeholders::_1, std::placeholders::_2);
And there's also no need for std::mem_fn
(it works, though), since std::bind
already handles member functions correctly (making the implicit this
argument an explicit first argument, like std::mem_fn
does).
You need to provide 2 arguments to std::bind or provide placeholders to provide them later:
std::function<float(int, int)> c = std::bind(&TestClass2::test3, obj2, 1, 2);
c(); //returns result
OR
std::function<float(int, int)> c = std::bind(&TestClass2::test3, obj2, std::placeholders::_1, std::placeholders::_2);
c(1, 2); //returns result
More information about std::bind is here.
Using visual C++ compiler (CTP 2012) i spied how they did std::function and deliviered my own solution to handle member functions
usage looks like: http://ideone.com/v5zfDn
class Window
{
public:
void Show( int number ) const
{
//...
}
void ShowDynamic( int number ) volatile
{
//...
}
};
void ShowWindows( int param )
{
//...
}
int main()
{
Window window;
typedef mezutils::Delegate< void( int ) > Notifier;
Notifier notifier;
notifier = &ShowWindows;
notifier( 0 );
notifier = Notifier( &window, &Window::Show );
notifier( 1 );
notifier = [](int x) { /*...*/ };
notifier( 2 );
void (*funpc)(int) = func;
notifier = funpc;
notifier( 3 );
notifier = [](int arg) { printf("asd %d\r\n",arg); };
notifier(4);
return 0;
}
delegate class looks like: http://ideone.com/DebQgR
of course it is a prototype made for fun, but i like it because it's clear
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With