![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
TutorialBoost , The Boost C++ Libraries BoostBook Documentation Subset , Chapter 13. Boost.Function
|
Preferred syntax | Portable syntax |
---|---|
|
|
Если ваш компилятор не отображается в этом списке, пожалуйста, попробуйте предпочтительный синтаксис и сообщите свои результаты в список Boost, чтобы мы могли поддерживать эту таблицу в актуальном состоянии.
Обертка функции определяется просто путем инстанцирования шаблона класса<function
>с желаемым типом возврата и типами аргументов, сформулированными как тип функции C++. Может быть представлено любое количество аргументов, вплоть до определенного предела реализации (10 является максимумом по умолчанию). Следующее объявляет обертку объекта функции<f
>, которая принимает два<int
>параметра и возвращает<float
>:
Preferred syntax | Portable syntax |
---|---|
|
|
По умолчанию обертки объектов функции пусты, поэтому мы можем создать объект функции, который можно назначить<f
>:
struct int_div { float operator()(int x, int y) const { return ((float)x)/y; }; };
f = int_div();
Теперь мы можем использовать<f
>для выполнения основной функции объекта<int_div
>:
std::cout << f(5, 3) << std::endl;
Мы можем назначить любой совместимый объект функции<f
>. Если бы<int_div
>было заявлено о приеме двух<long
>операндов, то к аргументам без вмешательства пользователя применялись бы неявные преобразования. Единственным ограничением на типы аргументов является то, что они являются CopyConstructible, поэтому мы можем использовать ссылки и массивы:
Preferred syntax |
---|
|
Portable syntax |
---|
|
void do_sum_avg(int values[], int n, int& sum, float& avg) { sum = 0; for (int i = 0; i < n; i++) sum += values[i]; avg = (float)sum / n; }
sum_avg = &do_sum_avg;
Вызов обертки функционального объекта, которая на самом деле не содержит функционального объекта, является нарушением предварительного условия, подобно попытке вызвать нулевой указатель функции и бросить исключение<bad_function_call
>. Мы можем проверить обертку пустого функционального объекта, используя ее в булевом контексте (она оценивает<true
>, если обертка не пуста) или сравнить ее с<0
>. Например:
if (f) std::cout << f(5, 3) << std::endl; else std::cout << "f has no target, so it is unsafe to call" << std::endl;
В качестве альтернативы<
метод возвращает, является ли обертка пустой.empty
>
Наконец, мы можем очистить целевую функцию, назначив ее<0
>или назвав функцию<
, например,clear
>()
f = 0;
Бесплатные указатели функций можно считать однотонными функциональными объектами с операторами вызовов функций const, и поэтому их можно непосредственно использовать с обертками функциональных объектов:
float mul_ints(int x, int y) { return ((float)x) * y; }
f = &mul_ints;
Обратите внимание, что<&
>не требуется, если вы не используете Microsoft Visual C++ версии 6.
Во многих системах обратный вызов часто вызывает членские функции конкретного объекта. Это часто называют «аргументным связыванием» и выходит за рамки Boost. Функция. Однако поддерживается прямое использование функций-членов, поэтому действителен следующий код:
struct X { int foo(int); };
Preferred syntax | Portable syntax |
---|---|
|
|
Существует несколько библиотек, поддерживающих связывание аргументов. Ниже приводится резюме трех таких библиотек:
Связь. Эта библиотека позволяет связывать аргументы для любого функционального объекта. Он легкий и очень портативный.
[ | ] [ | ] [ | ] Портативная [ | ]
---|---|---|---|
|
[!-- [ORIG_BEGIN]
[C++] Стандартная библиотека. Используяstd::bind1st
иstd::mem_fun
вместе, можно связать объект функции указателя с членом для использования с Boost. Функция:
Предпочтительный синтаксис | Портативный синтаксис |
---|---|
|
|
Ламбдабиблиотека. Эта библиотека обеспечивает мощный композиционный механизм для построения функциональных объектов, который использует очень естественный синтаксис C++. Lambda требует компилятора, который соответствует стандарту C++.
В некоторых случаях это дорого (или семантически неправильно), чтобы увеличить. Функция клонирует объект функции. В таких случаях можно запросить повышение. Функция содержит только ссылку на реальный объект функции. Это делается с использованием функций<ref
>и<cref
>для обертывания ссылки на объект функции:
Preferred syntax | Portable syntax |
---|---|
stateful_type a_function_object; | stateful_type a_function_object; |
Здесь<f
>не будет делать копии<a_function_object
>и<f2
>, когда речь идет о<f
><a_function_object
>. Кроме того, при использовании ссылок на функциональные объекты, повышается. Функция не будет выбрасывать исключения при назначении или строительстве.
Обертки функциональных объектов можно сравнить по<==
>или<!=
>с любым функциональным объектом, который может храниться в обертке. Если обертка функционального объекта содержит функциональный объект такого типа, она будет сравниваться с данным функциональным объектом (который должен быть либо равным, либо перегруженным<boost::function_equal
>). Например:
int compute_with_X(X*, int); f = &X::foo; assert(f == &X::foo); assert(&compute_with_X != f);
При сравнении с экземпляром<reference_wrapper
>адрес объекта в<reference_wrapper
>сравнивается с адресом объекта, хранящегося в обертке объекта функции:
a_stateful_object so1, so2; f =boost::ref
(so1); assert(f ==boost::ref
(so1)); assert(f == so1); // Only if a_stateful_object is EqualityComparable assert(f !=boost::ref
(so2));
Статья Tutorial раздела The Boost C++ Libraries BoostBook Documentation Subset Chapter 13. Boost.Function может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
:: Главная :: Chapter 13. Boost.Function ::
реклама |