boost::mem_fn является обобщением стандартных функций std::mem_fun и std::mem_fun_ref. Он поддерживает указатели функций-членов с более чем одним аргументом, и возвращенный объект функции может принять указатель, ссылку или интеллектуальный указатель на экземпляр объекта в качестве своего первого аргумента. mem_fn также поддерживает указатели на членов данных, рассматривая их как функции, не принимающие аргументов и возвращающие (const) ссылку на члена.
Назначение mem_fn двоякое. Во-первых, он позволяет пользователям вызывать функцию участника в контейнере со знакомой функцией
синтаксис, даже когда контейнер хранит умные указатели.
Во-вторых, он может быть использован в качестве строительного блока разработчиками библиотек, которые хотят рассматривать указатель на функцию члена как объект функции. Библиотека может определить расширенный алгоритм для каждого с перегрузкой формы:
где boost::mem_fn может быть ссылкой на эту страницу. В качестве примера см. документацию bind.
mem_fn берет один аргумент, указатель на участник, и возвращает объект функции, пригодный для использования со стандартными или определяемыми пользователем алгоритмами:
Возвращенный объект функции принимает те же аргументы, что и функция входного элемента плюс «гибкий» первый аргумент, который представляет экземпляр объекта.
Когда объект функции вызывается первым аргументом x, который не является ни указателем, ни ссылкой на соответствующий класс (X в примере выше), он использует get_pointer(x) для получения указателя от x. Авторы библиотеки могут «регистрировать» свои классы умных указателей, предоставляя соответствующий get_pointer перегрузка, позволяя mem_fn распознавать и поддерживать их.
[Примечание:get_pointer не ограничивается возвратом указателя. Любой объект, который может быть использован в функции члена вызова выражения (x->*pmf)(...) будет работать.]
[Примечание: библиотека использует неквалифицированный вызов get_pointer. Таким образом, с помощью поиска, зависящего от аргументов, он найдет get_pointer перегрузки, которые определяются в том же пространстве имен, что и соответствующий класс интеллектуальных указателей, в дополнение к любому boost::get_pointer перегрузки.
Все объекты функций, возвращаемые mem_fn, выставляют result_type typedef, который представляет тип возврата функции-члена. Для членов данных result_type определяется как тип члена.
Да. Для простого использования mem_fn обеспечивает дополнительную функциональность, которой не обладают стандартные адаптеры. Сложные выражения, которые используют std::bind1st, std::bind2nd или Boost.Compose вместе со стандартными адаптерами можно переписать с помощью boost::bind, который автоматически использует преимущества mem_fn.
Нет, если у вас нет на то веских причин. mem_fn не на 100% совместим со стандартными адаптерами. В частности, mem_fn не возвращает объекты типа std::[mem_fun[1>][ref]_t, и невозможно полностью описать тип первого аргумента, используя стандарт argument_type и first_argument_type вложенные типдефы. Библиотеки, которым нужны адаптивные функциональные объекты для функционирования, могут не понравиться mem_fn.
Непортативные расширения, как правило, должны по умолчанию отключаться, чтобы предотвратить блокировку поставщика. Если бы BOOST_MEM_FN_ENABLE_STDCALL был определен автоматически, вы могли бы случайно воспользоваться им, не понимая, что ваш код, возможно, больше не переносим. Кроме того, возможно, что соглашение вызова по умолчанию будет _stdcall, и в этом случае поддержка _stdcall приведет к дублированию определений.
namespaceboost{template<classT>T*get_pointer(T*p);template<classR,classT>unspecified-1mem_fn(R(T::*pmf)());template<classR,classT>unspecified-2mem_fn(R(T::*pmf)()const);template<classR,classT>unspecified-2-1mem_fn(RT::*pm);template<classR,classT,classA1>unspecified-3mem_fn(R(T::*pmf)(A1));template<classR,classT,classA1>unspecified-4mem_fn(R(T::*pmf)(A1)const);template<classR,classT,classA1,classA2>unspecified-5mem_fn(R(T::*pmf)(A1,A2));template<classR,classT,classA1,classA2>unspecified-6mem_fn(R(T::*pmf)(A1,A2)const);// implementation defined number of additional overloads for more arguments}
Все типы неуточненный-N, упомянутые в Синопсисе, являются CopyConstructible и Assignable. Их конструкторы копий и операторы присваивания не бросают исключений. неопределенный-N::result_type определяется как тип возврата указателя функции члена, переданного в качестве аргумента mem_fn (R в Синопсисе.) неопределенный-2-1::result_type определяется как R.
Возвращает: объект функции ϝ так, что выражение ϝ() эквивалентно (t)()pmf)()pmf)(), когда t является l-значением типа T или полученным, (get_pointer->*pmf)())())() в противном случае.
Некоторые платформы допускают несколько типов функций-членов, которые отличаются своей условностью вызова (правила, по которым вызывается функция: как передаются аргументы, как обрабатывается возвращаемое значение и кто очищает стек - если таковой имеется)
Например, функции API Windows и функции члена интерфейса COM используют соглашение вызовов, известное как _stdcall. Компоненты Borland VCL используют __fastcall. UDK, компонентная модель OpenOffice.org, использует _cdecl.
Для использования функций mem_fn с _stdcall#define макро BOOST_MEM_FN_ENABLE_STDCALL перед включением <boost/mem_fn.hpp>.
Для использования функций mem_fn с _fastcall#define макро BOOST_MEM_FN_ENABLE_FASTCALL перед включением <boost/mem_fn.hpp>.
Для использования функций mem_fn с _cdecl#define макро BOOST_MEM_FN_ENABLE_CDECL перед включением <boost/mem_fn.hpp>.
Лучше всего определить эти макросы в опциях проекта через -D в командной строке или в качестве первой строки в блоке перевода (файл .cpp), где используется mem_fn Несоблюдение этого правила может привести к неясным ошибкам, когда заголовок включает mem_fn.hpp до определения макроса.
[Примечание: это непортативное расширение. Он не является частью интерфейса.
[Примечание: Некоторые компиляторы обеспечивают лишь минимальную поддержку ключевого слова _stdcall]
Первоначальное предложение Рене Ягера использовать классы признаков для адаптации mem_fn к пользовательским интеллектуальным указателям вдохновило дизайн на основе get_pointer.
Многочисленные улучшения были предложены в течение формального периода обзора Ричардом Кроссли, Йенсом Маурером, Эдом Бреем и другими. Менеджером по обзору был Дарин Адлер.
Стив Аничини отметил, что интерфейсы COM используют _stdcall.
Дэйв Абрахамс модифицировал bind и mem_fn для поддержки void возвратов на недостающие компиляторы.
Даниэль Бельзле отметил, что UDK использует _cdecl.
Эта документация была портирована на Quickbook Agustín Bergé.
Последние изменения: 21 сентября 2016 в 14:46:30 GMT
Статья Chapter 1. Boost.Member Function раздела Chapter 1. Boost.Member Function может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.