The following program compiles with both gcc and clang, but is this actually standard C++11 or do both compilers choose to support it for convenience?
struct Foo {
int i;
void bar() { std::cout << i << std::endl; }
};
int main() {
std::function<void(Foo*)> method = &Foo::bar;
Foo myFoo{4};
method(&myFoo); // prints 4
}
This is certainly convenient, but I don't understand how/why it works.
The this pointer is a pointer accessible only within the nonstatic member functions of a class , struct , or union type. It points to the object for which the member function is called. Static member functions don't have a this pointer.
The pointer to member operators . * and ->* are used to bind a pointer to a member of a specific class object.
the constructor is the first function which get called. and we can access the this pointer via constructor for the first time. if we are able to get the this pointer before constructor call (may be via malloc which will not call constructor at all), we can call member function even before constructor call.
Yes, that is standard. [func.wrap.func.inv] specifies that the operator()(ArgTypes&&... args)
of std::function
calls
INVOKE
(f, std::forward<ArgTypes>(args)..., R)
(20.8.2), wheref
is the target object (20.8.1) of*this
.
(Where R
is the specified return type.)
[func.require] defines INVOKE
:
Define
INVOKE
(f, t1, t2, ..., tN)
as follows:
(t1.*f)(t2, ..., tN)
whenf
is a pointer to a member function of a classT
andt1
is an object of typeT
or a reference to an object of typeT
or a reference to an object of a type derived fromT
;
((*t1).*f)(t2, ..., tN)
whenf
is a pointer to a member function of a classT
andt1
is not one of the types described in the previous item;- […]
Note that the trailing R
in the call is used for the conversion to R
(the return type of the function
):
Define
INVOKE
(f, t1, t2, ..., tN, R)
asINVOKE
(f, t1, t2, ..., tN)
implicitly converted toR
.
The first and only argument you give is the pointer to the Foo
-object. The call to method
thus results in the call (void)((*t1).*f)()
which is, when written with your given values, equivalent to((*(&myFoo)).&Foo::bar)()
, which is equivalent to myFoo.bar()
.
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