Шаблон класса<function
>обеспечивает механизм реализации лениво оцененных функций. Синтаксически ленивая функция выглядит как обычная функция C/C++. Функциональный вызов выглядит знакомым и ощущается так же, как и обычные функции C++. Однако, в отличие от обычных функций, фактическое выполнение функции откладывается.
#include <boost/phoenix/function.hpp>
В отличие от обычных указателей функций или объектов функтора, которые должны быть явно связаны через функцию связи (см.Связь), типы аргументов этих функций автоматически лениво связаны.
Для того чтобы создать ленивую функцию, необходимо реализовать модель концепцииОбъекта полиморфных функций. Для функции, которая принимает аргументы<N
>, модельОбъекта Полиморфной Функциидолжна обеспечить:
- <
operator()
>, который принимает<N
>аргументы и реализует логику функции. Это также верно для обычных указателей функций.
- Вложенная метафункция<
result<Signature>
>или вложенный типдеф<result_type
>, послеповышения.РезультатПротокол
Например, следующий тип реализует концепцию FunctionEval, чтобы обеспечить ленивую факториальную функцию:
struct factorial_impl
{
template <typename Sig>
struct result;
template <typename This, typename Arg>
struct result<This(Arg const &)>
{
typedef Arg type;
};
template <typename Arg>
Arg operator()(Arg const & n) const
{
return (n <= 0) ? 1 : n * (*this)(n-1);
}
};
factorial.cpp
Реализовав тип<factorial_impl
>, мы можем объявить и инстанцировать ленивую<factorial
>функцию таким образом:
function<factorial_impl> factorial;
Вызывая ленивую функцию, такую как<factorial
>, не сразу выполняется функция объекта<factorial_impl
>. Вместо этогоактеробъект создается и возвращается вызывающему. Пример:
factorial(arg1)
Это не более чем возвращение актера. Второй вызов функции вызовет фактическую факторную функцию. Пример:
std::cout << factorial(arg1)(4);
Распечатать «24».
Обратите внимание, что в некоторых случаях (например, для функциональных объектов с состоянием) экземпляр моделиобъекта полиморфной функцииможет быть передан конструктору. Пример:
function<factorial_impl> factorial(ftor);
где ftor является экземпляром factorial_impl (в этом случае нет необходимости, так как<factorial_impl
>не требует никакого состояния).
![[Important]](/img/important.png) |
Important |
Будьте осторожны при использовании функциональных объектов с состоянием, потому что они часто копируются неоднократно, и состояние может изменяться в одной из копий, а не в оригинале. |