#2 Moderator* - Reputation: 5387
Posted 15 November 2012 - 01:14 AM
std::function<int (int, int)> func; // Wrapper creation using
// template class 'function'.
std::plus<int> add; // 'plus' is declared as 'template<class T> T plus( T, T ) ;'
// then 'add' is type 'int add( int x, int y )'.
func = add; // OK - Parameters and return types are the same.
int a = func (1, 2); // NOTE: if the wrapper 'func' does not refer to any function,
// the exception 'std::bad_function_call' is thrown.
std::function<bool (short, short)> func2 ;
if (!func2) { // True because 'func2' has not yet been assigned a function.
bool adjacent(long x, long y);
func2 = &adjacent; // OK - Parameters and return types are convertible.
struct Test {
bool operator()(short x, short y);
};
Test car;
func = std::ref(car); // 'std::ref' is a template function that returns the wrapper
// of member function 'operator()' of struct 'car'.
}
func = func2; // OK - Parameters and return types are convertible.
The particularly nice tidbit (for me) is being able to use functions and functors without changing func's definition/type.
#3 Members - Reputation: 5815
Posted 15 November 2012 - 02:04 AM
Edited by Álvaro, 15 November 2012 - 02:05 AM.
#4 GDNet+ - Reputation: 1731
Posted 15 November 2012 - 03:15 AM
Function pointers cannot as far as I recall , and sure interfaces cannot.
So they're really the only "complete" way to deal with lambdas, a thing which I consider to be a bit ugly, but that's it.
#5 Members - Reputation: 1408
Posted 15 November 2012 - 07:33 AM
class Tree {
Walk(void (*callback)(Node*));
};It is common to also have an extra argument of the type "void *" that will be forwarded to the callback function. I think this is a typical case that a closure would be used, is it now possible?Something like:
void Callback1(Node*, int); void Callback2(Node*, int, float); Tree *t; auto cb1 = std::bind(Callback1, _1, 77); t->Walk(cb1); auto cb2 = std::bind(Callback1, _1, 77, 1.0f); t->Walk(cb2);If possible, what is the recommended way to implement this?
#6 Moderators - Reputation: 4636
Posted 15 November 2012 - 07:55 AM
Edited by Brother Bob, 15 November 2012 - 07:56 AM.
#7 Members - Reputation: 1408
Posted 15 November 2012 - 09:20 AM
If you make Tree::Walk take an std::function<void(Node *)>, you can then do t->Walk([](Node *n){Callback1(n, 77);}). The benefit, as stated above, is that you can pass anything that is callable with a Node-pointer and have no return value: a function pointer, a closure and an old-style function object, and your code doesn't have to know or take special action for the different types of callable objects.
I see, it is that simple! This is something I should be able to use to great advantage.






