How to get this pointer from std::function?
Asked Answered
M

2

5

Since std::function can hold member functions, so it must store a pointer to the object instance somewhere.

How can I fetch the this pointer from a std::function that holds a member function?

Marielamariele answered 1/4, 2013 at 16:53 Comment(3)
Did you take a look at e.g. en.cppreference.com/w/cpp/utility/functional/function?Balenciaga
@OliCharlesworth. Of course I did. Tell me if I was blind to the answer.Marielamariele
I'm pretty sure that this sort of information is deliberately not exposed in the library, and thus inaccessible in a portable way.Narcoanalysis
V
9

An object of type std::function holds a callable object. A pointer to member function is a kind of callable object; it can be called with an argument of the appropriate class type, plus any additional arguments that it needs. For example:

struct S {
    void f(int);
};
std::function<void(S, int)> g(&S::f);

To call it, pass an object of type S:

S s;
g(s, 3);

Note that the std::function object does not hold an S object; it's only when you call it that the function pointer gets bound to an object.

Viola answered 1/4, 2013 at 17:5 Comment(9)
My goal is to unwrap lambdas I passed as std::function to another function. How can I do so then? By unwrapping I mean to split it up into a this pointer and a static function pointer using std::function::target for further processing.Marielamariele
@danijar: Why don't you put your goal into your question instead? Your question makes little sense.Husha
@Marielamariele you can make your own function object which binds a this pointer and allows retrieval.Sparker
@Marielamariele if it's a static function, there is no bound object instance.Litmus
When I store a lambda expression as std::function, it the this pointer already bound then?Marielamariele
@Marielamariele - a lambda function doesn't necessarily have a this pointer. Whatever arguments it captures are stored in the object, and there is no mechanism for pulling them out. If you need to do that, a lambda is probably not what you should use.Viola
@PeteBecker. Thanks, so the reference is kind of bound like std::bind would do, if I understand right. But why does .target() return a null pointer then?Marielamariele
@Marielamariele - std::function::target is a template function; when you call it you have to specify the type that you're looking for. If that's the type stored in the object, you get back a pointer to the callable object. If it's not the right type you get back a null pointer.Viola
@PeteBecker. The lambda comes as a parameter of the type function<Handle<Value>(Arguments const &)>. I try to cast that to a raw function pointer with the signature Handle<Value>(Arguments const &). But, maybe because I used the capture clause, it returns a null pointer. But you answered the question, I asked. If you still want to help me, please follow the link I posted as comment under the question.Marielamariele
H
0

You can wrap the std::function template in a functionally similar template, but one that exposes the functions you want (like sorting by address or whatever else)

See Stroika Function Template for an example implementation.

It works just like std::function (and lets you retrieve the aggregated std::function), but also keeps extra info to allow sorting and so on (handy to store the function pointers in a map and have object identity to later remove them).

Hiddenite answered 27/11, 2022 at 16:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.