Читаем Язык программирования C++. Пятое издание полностью

// ошибка: для вызова через указатель на член класса следует

// использовать оператор .* или ->*

find_if(svec.begin(), svec.end(), fp);

Алгоритм find_if() ожидает вызываемый объект, но предоставляется указатель на функцию-член fp. Этот вызов не будет откомпилирован, поскольку код в алгоритме find_if() выполняет примерно такой оператор:

// проверяет применимость данного предиката к текущему элементу,

// возвращает true

if (fp(*it)) // ошибка: для вызова через указатель на член класса

             // следует использовать оператор ->*

Использование шаблона function для создания вызываемого объекта

Один из способов получения вызываемого объекта из указателя на функцию-член подразумевает использование библиотечного шаблона function (см. раздел 14.8.3):

function fcn = &string::empty;

find_if(svec.begin(), svec.end(), fcn);

Здесь шаблону function указано, что empty() — это функция, которая может быть вызвана со строкой и возвращает значение типа bool. Обычно объект, для которого выполняется функция-член, передается неявному параметру this. Когда шаблон function используется при создании вызываемого объекта для функции-члена, следует преобразовать код так, чтобы сделать этот неявный параметр явным.

Когда объект шаблона function содержит указатель на функцию-член, класс function знает, что для вызова следует использовать соответствующий оператор указателя на член класса. Таким образом, можно предположить, что у функции find_if() будет код наподобие следующего:

// если it является итератором в функции find_if(), то *it - объект

// в заданном диапазоне

if (fcn(*it)) // fcn - имя вызываемого объекта в функции find_if()

Его и выполнит шаблон класса function, используя соответствующий оператор указателя на член класса. Класс function преобразует этот вызов в такой код:

// если it является итератором в функции find_if(), то *it - объект

// в заданном диапазоне

if (((*it).*p)()) // p - указатель на функцию-член в функции fcn

При определении объекта шаблона function следует указать тип функции, сигнатура которой определяет представляемые вызываемые объекты. Когда вызываемой объект является функцией-членом, первый параметр сигнатуры должен представить (обычно неявный) объект, для которого будет выполнена функция-член. Передаваемая шаблону function сигнатура должна определять, будет ли объект передан как указатель или как ссылка.

При определении вызываемого объекта fcn() было известно, что нужно вызвать функцию find_if() для последовательности строковых объектов. Следовательно, от шаблона function требовалось создать вызываемый объект, получающий объекты класса string. Если бы вектор содержал указатели на тип string, от шаблона function требовалось бы ожидать указатель:

vector pvec;

function fp = &string::empty;

// fp получает указатель на string и использует оператор ->* для вызова

// функции empty()

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); // f получает string или string*

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных