6

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

Xeo
  • 129,499
  • 52
  • 291
  • 397
p12
  • 1,161
  • 8
  • 23
  • 3
    How can it be a typo when they specifically talk about "pointer to member data"? Also, the `(t1.*f)(...)` case is dealt with directly above. – Xeo Sep 28 '12 at 10:40
  • 1
    @Xeo: Member data may be a callable object. – p12 Sep 28 '12 at 10:42

1 Answers1

10

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.

Community
  • 1
  • 1
Xeo
  • 129,499
  • 52
  • 291
  • 397
  • @Cubbi: You forgot to fix some wording on the `std::mem_fn` page, fixed that (and also the member typedef errors). :) – Xeo Oct 20 '12 at 11:09