$ 20.8.2 of the standard describes the INVOKE facility that is mostly used to describe how callables are called with variadic argument lists throughout the standard library:
Define INVOKE (f, t1, t2, ..., tN) as follows:
—
(t1.*f)(t2, ..., tN)
when f is a pointer to a member function of a class T and t1 is an object of type T or a reference to an object of type T or a reference to an object of a type derived from T;—
((*t1).*f)(t2, ..., tN)
when f is a pointer to a member function of a class T and t1 is not one of the types described in the previous item;—
t1.*f
when N == 1 and f is a pointer to member data of a class T and t1 is an object of type T or a reference to an object of type T or a reference to an object of a type derived from T;—
(*t1).*f
when N == 1 and f is a pointer to member data of a class T and t1 is not one of the types described in the previous item;—
f(t1, t2, ..., tN)
in all other cases.
What are the third and the fourth item for? As far as I can tell, they don't call f
even if f
is callable. What's the user case for them. Maybe it's a typo in the standard and *f()
was intended?
With the approval of C++11, TR1 is officially incorporated into standard C++ standard, along with new libraries that have been added since TR1. Here are some of the C++11 Standard Library features: Unquestionably, the most important addition to C++11 from a programmer's perspective is concurrency.
Consequently, C++11 provides some rules/guarantees for the programmer to avoid data races: A C++ standard library function shall not directly or indirectly access objects accessible by threads other than the current thread unless the objects are accessed directly or indirectly via the function's arguments, including this .
Please help improve it to make it understandable to non-experts, without removing the technical details. C++11 is a version of the ISO / IEC 14882 standard for the C++ programming language. C++11 replaced the prior version of the C++ standard, called C++03, and was later replaced by C++14.
C++11 allows constructors to call other peer constructors (termed delegation). This allows constructors to utilize another constructor's behavior with a minimum of added code. Delegation has been used in other languages e.g., Java, Objective-C.
INVOKE
is specified like that because you can actually bind member data pointers (through bind
and mem_fn
):
§20.8.10 [func.memfn]
template<class R, class T>
unspecified
mem_fn(R T::* pm);
p1 Returns: A simple call wrapper (20.8.1)
fn
such that the expressionfn(t, a2, ..., aN)
is equivalent toINVOKE(pm, t, a2, ..., aN)
(20.8.2).fn
shall have a nested typeresult_type
that is a synonym for the return type ofpm
whenpm
is a pointer to member function.
I don't think that special wording would exist if you couldn't bind member data pointers.
#include <functional>
#include <iostream>
struct X{
int n = 5;
};
int main(){
X x;
auto f = std::mem_fn(&X::n);
std::cout << f(&x) << "\n";
}
Output: 5
Live example.
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