Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does INVOKE facility in the C++11 standard refer to data members?

$ 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?

like image 460
p12 Avatar asked Sep 28 '12 10:09

p12


People also ask

What's new in C++11 standard library?

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.

How to avoid data races in C++11?

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 .

What is the C++11 standard?

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.

What is C++11 delegation?

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.


1 Answers

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>
unspecifiedmem_fn(R T::* pm);

p1 Returns: A simple call wrapper (20.8.1) fn such that the expression fn(t, a2, ..., aN) is equivalent to INVOKE(pm, t, a2, ..., aN) (20.8.2). fn shall have a nested type result_type that is a synonym for the return type of pm when pm 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.

like image 79
Xeo Avatar answered Oct 24 '22 21:10

Xeo