std::function
| Определено в заголовочном файле <functional>
|
||
template< class > class function; /* не определено */ |
(начиная с C++11) | |
template< class R, class... Args > class function<R(Args...)>; |
(начиная с C++11) | |
Шаблон класса std::function это полиморфная обёртка функции общего назначения. Экземпляры std::function могут хранить, копировать и вызывать любые CopyConstructible Callable цели -- функции (через указатели на них), лямбда-выражения, выражения привязки или другие объекты-функции, а также указатели на функции-элементы и указатели на элементы-данных.
Сохранённый вызываемый объект называется целью объекта std::function. Если std::function не содержит цели, он называется пустым. Вызов цели пустого std::function приводит к возникновению исключения std::bad_function_call.
std::function соответствует требованиям CopyConstructible и CopyAssignable.
Типы-элементы
| Тип | Определение |
result_type
|
R
|
argument_type(устарело в C++17)(удалено в C++20)
|
T if sizeof...(Args)==1 и T является первым и единственным типом в Args...
|
first_argument_type(устарело в C++17)(удалено в C++20)
|
T1 if sizeof...(Args)==2 и T1 является первым из двух типов в Args...
|
second_argument_type(устарело в C++17)(удалено в C++20)
|
T2 if sizeof...(Args)==2 и T2 является вторым из двух типов в Args...
|
Функции-элементы
создаёт новый экземпляр std::function (public функция-элемент) | |
уничтожает экземпляр std::function (public функция-элемент) | |
| присваивает новую цель (public функция-элемент) | |
| обменивает содержимое (public функция-элемент) | |
(удалено в C++17) |
присваивает новую цель (public функция-элемент) |
| проверяет, содержится ли цель (public функция-элемент) | |
| вызывает цель (public функция-элемент) | |
Доступ к цели | |
получает typeid сохранённой цели (public функция-элемент) | |
| получает указатель на сохранённую цель (public функция-элемент) | |
Функции, не являющиеся элементами
(C++11) |
специализация алгоритма std::swap (шаблон функции) |
(удалено в C++20) |
сравнивает std::function с nullptr (шаблон функции) |
Вспомогательные классы
(C++11) (до C++17) |
специализация свойства типа std::uses_allocator (специализация шаблона класса) |
Принципы вывода(начиная с C++17)
Примечание
|
Следует соблюдать осторожность, когда |
(до C++23) |
|
Если |
(начиная с C++23) |
std::function<const int&()> F([]{ return 42; }); // Ошибка начиная с C++23: невозможно
// привязать возвращённую ссылку
// к временному объекту
int x = F(); // Неопределённое поведение до C++23: результатом F() является висячая ссылка
std::function<int&()> G([]()->int& { static int i{0x2A}; return i; }); // OK
std::function<const int&()> H([i{052}]->const int& { return i; }); // OK
Пример
#include <functional>
#include <iostream>
struct Foo {
Foo(int num) : num_(num) {}
void print_add(int i) const { std::cout << num_+i << '\n'; }
int num_;
};
void print_num(int i)
{
std::cout << i << '\n';
}
struct PrintNum {
void operator()(int i) const
{
std::cout << i << '\n';
}
};
int main()
{
// сохраняет свободную функцию
std::function<void(int)> f_display = print_num;
f_display(-9);
// сохраняет лямбду
std::function<void()> f_display_42 = []() { print_num(42); };
f_display_42();
// сохраняет результат вызова std::bind
std::function<void()> f_display_31337 = std::bind(print_num, 31337);
f_display_31337();
// сохраняет вызов функции-элемента
std::function<void(const Foo&, int)> f_add_display = &Foo::print_add;
const Foo foo(314159);
f_add_display(foo, 1);
f_add_display(314159, 1);
// сохраняет вызов метода доступа к элементу данных
std::function<int(Foo const&)> f_num = &Foo::num_;
std::cout << "num_: " << f_num(foo) << '\n';
// сохраняет вызов функции-элемента и объект
using std::placeholders::_1;
std::function<void(int)> f_add_display2 = std::bind( &Foo::print_add, foo, _1 );
f_add_display2(2);
// сохраняет вызов функции-элемента и указатель на объект
std::function<void(int)> f_add_display3 = std::bind( &Foo::print_add, &foo, _1 );
f_add_display3(3);
// сохраняет вызов функционального объекта
std::function<void(int)> f_display_obj = PrintNum();
f_display_obj(18);
auto factorial = [](int n) {
// сохраняет лямбда-объект для эмуляции "рекурсивной лямбды";
// осведомлены о дополнительных накладных расходах
std::function<int(int)> fac = [&](int n){ return (n < 2) ? 1 : n*fac(n-1); };
// обратите внимание, что "auto fac = [&](int n){...};" не работает в рекурсивных
// вызовах
return fac(n);
};
for (int i{5}; i != 8; ++i)
std::cout << i << "! = " << factorial(i) << "; ";
std::cout << '\n';
}
Возможный вывод:
-9
42
31337
314160
314160
num_: 314159
314161
314162
18
5! = 120; 6! = 720; 7! = 5040;
Смотрите также
(C++23) |
обёртывает вызываемый объект любого типа с указанной сигнатурой вызова функции (шаблон класса) |
(C++11) |
исключение, возникающее при вызове пустой std::function (класс) |
(C++11) |
создаёт объект функцию из указателя на элемент (шаблон функции) |
| typeid | Запрашивает информацию о типе, возвращая объект std::type_info, представляющий тип.
|