|  | 
|      | 
|  | 
| 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 ::
| реклама |