Purpose of std::function

Started by
5 comments, last by larspensjo 11 years, 5 months ago
What is the purpose of this class template?

I suppose it simplifies the syntax for function pointers. But does it give you anything else but syntactic sugaring?
[size=2]Current project: Ephenation.
[size=2]Sharing OpenGL experiences: http://ephenationopengl.blogspot.com/
Advertisement
Sure. Try this with just function pointers (taken from Wikipedia):

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 [font=courier new,courier,monospace]func[/font]'s definition/type.
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]
Constalks is right. If you need to pass a callback to a piece of code, make sure it accepts an std::function, and then you can use it with function pointers or with functors of any type. This is particularly useful if you want the pass a member function of a particular object as a callback.
I think it's worth noticing [font=courier new,courier,monospace]std::function[/font] is correctly mapped even when capture lists are used with lambdas.
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.

Previously "Krohm"

Thanks for the answers. There is a case I am specifically interested in, but I couldn't find out if it is now possible. I want to use closures with callbacks. Take this example, with a tree walker and a callback for every node in the tree:
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?
[size=2]Current project: Ephenation.
[size=2]Sharing OpenGL experiences: http://ephenationopengl.blogspot.com/
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.

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.
[size=2]Current project: Ephenation.
[size=2]Sharing OpenGL experiences: http://ephenationopengl.blogspot.com/

This topic is closed to new replies.

Advertisement