$ 20.8.2 стандарта описывает средство INVOKE, которое в основном используется для описания того, как вызываемые объекты вызываются с помощью списков аргументов с переменным числом аргументов во всей стандартной библиотеке:

Определите INVOKE (f, t1, t2, ..., tN) следующим образом:

- (t1.*f)(t2, ..., tN), когда f - указатель на функцию-член класса T, а t1 - объект тип T или ссылка на объект типа T или ссылка на объект типа, производного от T;

- ((*t1).*f)(t2, ..., tN), когда f является указателем на функцию-член класса T, а t1 не является одним из типы, описанные в предыдущем пункте;

- t1.*f, когда N == 1 и f - указатель на данные члена класса T, а t1 - объект типа T или ссылка на объект типа T или ссылка на объект типа, производного от T;

- (*t1).*f, когда N == 1 и f является указателем на данные члена класса T, а t1 не является одним из типов описано в предыдущем пункте;

- f(t1, t2, ..., tN) во всех остальных случаях.

Для чего нужны третий и четвертый предметы? Насколько я могу судить, они не вызывают f, даже если f вызывается. Какой для них пользовательский кейс. Может быть, это опечатка в стандарте и предназначалась *f()?

6
p12 28 Сен 2012 в 14:37
3
Как это может быть опечаткой, когда конкретно говорят об «указателе на данные члена»? Кроме того, случай (t1.*f)(...) рассматривается непосредственно выше.
 – 
Xeo
28 Сен 2012 в 14:40
1
@Xeo: данные члена могут быть вызываемым объектом.
 – 
p12
28 Сен 2012 в 14:42

1 ответ

Лучший ответ

INVOKE указывается так, потому что вы действительно можете привязать указатели данных членов (через bind и mem_fn):

§20.8.10 [func.memfn]

template<class R, class T>
unspecified mem_fn(R T::* pm);

p1 Возвращает: Простая оболочка вызова (20.8.1) fn, такая, что выражение fn(t, a2, ..., aN) эквивалентно INVOKE(pm, t, a2, ..., aN) (20.8.2). fn должен иметь вложенный тип result_type, который является синонимом возвращаемого типа pm , когда pm является указателем на функцию-член .

Я не думаю, что существовала бы особая формулировка, если бы вы не могли привязать указатели данных-членов.

#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";
}

Выход: 5

Живой пример.

10
Community 20 Июн 2020 в 12:12
@Cubbi: Вы забыли исправить некоторые формулировки на странице std::mem_fn, исправили это (а также ошибки typedef членов). :)
 – 
Xeo
20 Окт 2012 в 15:09