//
//
find_if(svec.begin(), svec.end(), fp);
Алгоритм find_if()
ожидает вызываемый объект, но предоставляется указатель на функцию-член fp
. Этот вызов не будет откомпилирован, поскольку код в алгоритме find_if()
выполняет примерно такой оператор:
//
//
if (fp(*it)) //
//
function
для создания вызываемого объектаОдин из способов получения вызываемого объекта из указателя на функцию-член подразумевает использование библиотечного шаблона function
(см. раздел 14.8.3):
function
find_if(svec.begin(), svec.end(), fcn);
Здесь шаблону function
указано, что empty()
— это функция, которая может быть вызвана со строкой и возвращает значение типа bool
. Обычно объект, для которого выполняется функция-член, передается неявному параметру this
. Когда шаблон function
используется при создании вызываемого объекта для функции-члена, следует преобразовать код так, чтобы сделать этот неявный параметр явным.
Когда объект шаблона function
содержит указатель на функцию-член, класс function
знает, что для вызова следует использовать соответствующий оператор указателя на член класса. Таким образом, можно предположить, что у функции find_if()
будет код наподобие следующего:
//
//
if (fcn(*it)) //
Его и выполнит шаблон класса function
, используя соответствующий оператор указателя на член класса. Класс function
преобразует этот вызов в такой код:
//
//
if (((*it).*p)()) //
При определении объекта шаблона function
следует указать тип функции, сигнатура которой определяет представляемые вызываемые объекты. Когда вызываемой объект является функцией-членом, первый параметр сигнатуры должен представить (обычно неявный) объект, для которого будет выполнена функция-член. Передаваемая шаблону function
сигнатура должна определять, будет ли объект передан как указатель или как ссылка.
При определении вызываемого объекта fcn()
было известно, что нужно вызвать функцию find_if()
для последовательности строковых объектов. Следовательно, от шаблона function
требовалось создать вызываемый объект, получающий объекты класса string
. Если бы вектор содержал указатели на тип string
, от шаблона function
требовалось бы ожидать указатель:
vector
function
//
//
find_if(pvec.begin(), pvec.end(), fp);
mem_fn
для создания вызываемого объектаfunction
, следует предоставить сигнатуру вызова члена, который предстоит вызвать. Но можно позволить компилятору вывести тип функции-члена при использовании другого библиотечного средства, шаблона mem_fn
, определенного, как и шаблон function
, в заголовке functional
. Как и шаблон function
, шаблон mem_fn
создает вызываемый объект из указателя на член класса. В отличие от шаблона function
, шаблон mem_fn
выведет тип вызываемого объекта из типа указателя на член класса:
find_if(svec.begin(), svec.end(), mem_fn(&string::empty));
Здесь шаблон mem_fn(&string::empty)
создает вызываемый объект, получающий строковый аргумент и возвращающий логическое значение.
Вызываемый объект, созданный шаблоном mem_fn
, может быть вызван для объекта или указателя:
auto f = mem_fn(&string::empty); //