Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Chapter 1. Boost.Member Function

Boost , Chapter 1. Boost.Member Function ,

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

Chapter 1. Boost.Member Function

Распространяется по лицензии Boost Software License, версия 1.0.

boost::mem_fn является обобщением стандартных функций std::mem_fun и std::mem_fun_ref. Он поддерживает указатели функций-членов с более чем одним аргументом, и возвращенный объект функции может принять указатель, ссылку или интеллектуальный указатель на экземпляр объекта в качестве своего первого аргумента. mem_fn также поддерживает указатели на членов данных, рассматривая их как функции, не принимающие аргументов и возвращающие (const) ссылку на члена.

Назначение mem_fn двоякое. Во-первых, он позволяет пользователям вызывать функцию участника в контейнере со знакомой функцией

std::for_each(v.begin(), v.end(), boost::mem_fn(&Shape::draw));

синтаксис, даже когда контейнер хранит умные указатели.

Во-вторых, он может быть использован в качестве строительного блока разработчиками библиотек, которые хотят рассматривать указатель на функцию члена как объект функции. Библиотека может определить расширенный алгоритм для каждого с перегрузкой формы:

template<class It, class R, class T> void for_each(It first, It last, R (T::*pmf) ())
{
    std::for_each(first, last, boost::mem_fn(pmf));
}

это позволит создать удобный синтаксис:

for_each(v.begin(), v.end(), &Shape::draw);

При документировании функции автор библиотеки просто скажет:

template<class It, class R, class T> void for_each(It first, It last, R (T::*pmf) ());
  • Эффекты: Эквивалент std::for_each(first, last, boost::mem_fn(pmf)).

где boost::mem_fn может быть ссылкой на эту страницу. В качестве примера см. документацию bind.

mem_fn берет один аргумент, указатель на участник, и возвращает объект функции, пригодный для использования со стандартными или определяемыми пользователем алгоритмами:

struct X
{
    void f();
};
void g(std::vector<X> & v)
{
    std::for_each(v.begin(), v.end(), boost::mem_fn(&X::f));
};
void h(std::vector<X *> const & v)
{
    std::for_each(v.begin(), v.end(), boost::mem_fn(&X::f));
};
void k(std::vector<boost::shared_ptr<X> > const & v)
{
    std::for_each(v.begin(), v.end(), boost::mem_fn(&X::f));
};

Возвращенный объект функции принимает те же аргументы, что и функция входного элемента плюс «гибкий» первый аргумент, который представляет экземпляр объекта.

Когда объект функции вызывается первым аргументом 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 приведет к дублированию определений.

namespace boost
{
    template<class T> T * get_pointer(T * p);
    template<class R, class T> unspecified-1 mem_fn(R (T::*pmf) ());
    template<class R, class T> unspecified-2 mem_fn(R (T::*pmf) () const);
    template<class R, class T> unspecified-2-1 mem_fn(R T::*pm);
    template<class R, class T, class A1> unspecified-3 mem_fn(R (T::*pmf) (A1));
    template<class R, class T, class A1> unspecified-4 mem_fn(R (T::*pmf) (A1) const);
    template<class R, class T, class A1, class A2> unspecified-5 mem_fn(R (T::*pmf) (A1, A2));
    template<class R, class T, class A1, class A2> unspecified-6 mem_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.

template<class T> T * get_pointer(T * p)
  • Возврат: p.
  • Броски: Ничего.
template<class R, class T> unspecified-1 mem_fn(R (T::*pmf) ())
  • Возвращает: объект функции ϝ так, что выражение ϝ() эквивалентно (t)()pmf)()pmf)(), когда t является l-значением типа T или полученным, (get_pointer->*pmf)())())() в противном случае.
  • Броски: Ничего.
template<class R, class T> unspecified-2 mem_fn(R (T::*pmf) () const)
  • Возвращает: объект функции ϝ так, что выражение ϝ(.t.*pmf)() имеет тип tget_pointert)()pmf в противном случае.
  • Броски: Ничего.
template<class R, class T> unspecified-2-1 mem_fn(R T::*pm)
  • Возвращает: объект функции ϝ так, что выражение ϝ() эквивалентно t.*pm, когда t имеет тип T[]->*pm в противном случае.
  • Броски: Ничего.
template<class R, class T, class A1> unspecified-3 mem_fn(R (T::*pmf) (A1))
  • Возвращает: объект функции ϝ так, что выражение ϝ().*pmf)a1, когда tT или полученное, (get_pointer->*pmf)a1 в противном случае.
  • Броски: Ничего.
template<class R, class T, class A1> unspecified-4 mem_fn(R (T::*pmf) (A1) const)
  • Возвращает: объект функции ϝ так, что выражение ϝ().*pmf) имеет тип t[2>]get_pointer->pmf в противном случае.
  • Броски: Ничего.
template<class R, class T, class A1, class A2> unspecified-5 mem_fn(R (T::*pmf) (A1, A2))
  • Возвращает: объект функции ϝ так, что выражение ϝ(,a1)t.pmf)a1, когда a2 является l-значением типа tget_pointer->pmf,a1,a2 в противном случае.
  • Броски: Ничего.
template<class R, class T, class A1, class A2> unspecified-6 mem_fn(R (T::*pmf) (A1, A2) const)
  • Возвращает: объект функции ϝ так, что выражение ϝ,a1.pmf.a1,a1,a2 имеет тип t иное, get_pointerpmf>.
  • Броски: Ничего.

Эта реализация поддерживает членские функции до восьми аргументов. Это не неотъемлемое ограничение дизайна, а деталь реализации.

Некоторые платформы допускают несколько типов функций-членов, которые отличаются своей условностью вызова (правила, по которым вызывается функция: как передаются аргументы, как обрабатывается возвращаемое значение и кто очищает стек - если таковой имеется)

Например, функции 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.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-19 16:45:27/0.032763004302979/1