std::function<R(Args...)>::function
来自cppreference.com
< cpp | utility | functional | function
function() noexcept; | (1) | (C++11 起) |
function( std::nullptr_t ) noexcept; | (2) | (C++11 起) |
function( const function& other ); | (3) | (C++11 起) |
(4) | ||
function( function&& other ); | (C++11 起) (C++20 前) | |
function( function&& other ) noexcept; | (C++20 起) | |
template< class F > function( F&& f ); | (5) | (C++11 起) |
template< class Alloc > function( std::allocator_arg_t, const Alloc& alloc ) noexcept; | (6) | (C++11 起) (C++17 移除) |
template< class Alloc > function( std::allocator_arg_t, const Alloc& alloc, | (7) | (C++11 起) (C++17 移除) |
template< class Alloc > function( std::allocator_arg_t, const Alloc& alloc, | (8) | (C++11 起) (C++17 移除) |
template< class Alloc > function( std::allocator_arg_t, const Alloc& alloc, | (9) | (C++11 起) (C++17 移除) |
template< class F, class Alloc > function( std::allocator_arg_t, const Alloc& alloc, F f ); | (10) | (C++11 起) (C++17 移除) |
从各种来源构造 std::function
。
如果 other 为空,那么 *this 在构造完成时也为空。
4) 将 other 的目标移动到 *this 的目标。
如果 other 为空,那么 *this 在构造完成时也为空。
构造完成时 other 处于有效但未指定的状态。
如果 f 是空函数指针、空成员指针或某个
std::function
特化的空值,那么 *this 在构造完成时为空。 此重载只有在满足以下所有条件时才会参与重载决议:
| (C++23 起) |
- std::decay<F>::type 类型的左值对实参类型
Args...
和返回类型R
可调用。
如果 std::is_copy_constructible_v<std::decay_t<F>> 或 std::is_constructible_v<std::decay_t<F>, F> 是 false,那么程序非良构。 | (C++23 起) |
如果
F
不可复制构造 (CopyConstructible) ,那么行为未定义。6-10) 同 (1-5),但将 alloc 用于为
std::function
会用到的任何内部数据结构分配内存。当目标是函数指针或 std::reference_wrapper 时,保证使用小对象优化,即始终直接存储这些目标于 std::function 对象中,不发生动态内存分配。可以构造其他大对象于动态分配的存储中,并由 std::function 对象通过指针访问。
参数
other | - | 用于初始化 *this 的函数对象 |
f | - | 用于初始化 *this 的可调用对象 |
alloc | - | 用于内部内存分配的分配器 (Allocator) |
类型要求 | ||
-Alloc 必须满足分配器 (Allocator) 。 |
异常
3,8,9) 如果 other 的目标是函数指针或 std::reference_wrapper,那么不抛出异常,否则可能抛出 std::bad_alloc 或用于复制或移动存储的可调用对象的构造函数所抛的任何异常。
4) 如果 other 的目标是函数指针或 std::reference_wrapper,那么不抛出异常,否则可能抛出 std::bad_alloc 或用于复制或移动存储的可调用对象的构造函数所抛的任何异常。 | (C++20 前) |
注解
std::function
的分配器支持说明贫乏,且实现不一致。一些实现完全不提供重载 (6-10),一些提供重载但忽略提供的分配器参数,而一些实现提供重载并将提供的分配器用于构造,但不在重赋值 std::function
时使用。结果,C++17 中移除了分配器支持。
示例
运行此代码
#include <functional> #include <iostream> #include <utility> void print_num(int i) { std::cout << "print_num(" << i << ")\n"; } int main() { std::function<void(int)> func1; // (1) 空构造函数 try { func1(333 << 1); } catch (const std::bad_function_call& ex) { std::cout << "1) " << ex.what() << '\n'; } std::function<void(int)> func2{nullptr}; // (2) 空构造函数 try { func1(222 * 3); } catch (const std::bad_function_call& ex) { std::cout << "2) " << ex.what() << '\n'; } func1 = print_num; // 用赋值运算符初始化 func1 std::function<void(int)> func3{func1}; // (3) 复制构造函数 func3(33); std::function<void(int)> func4{std::move(func3)}; // (4) 移动构造函数, // func3 处于未指明的状态 func4(44); std::function<void(int)> func5{print_num}; // (5) 用函数调用构造函数 func5(55); // (5) 用 lambda 调用构造函数 std::function<void(int)> func6([](int i) { std::cout << "lambda(" << i << ")\n"; }); func6(66); }
可能的输出:
1) bad_function_call 2) bad_function_call print_num(33) print_num(44) print_num(55) lambda(66)
缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。
缺陷报告 | 应用于 | 出版时的行为 | 正确行为 |
---|---|---|---|
LWG 2132 | C++11 | 重载 (5,10) 可能有歧义 | 已约束 |
LWG 2774 | C++11 | 重载 (5,10) 会进行一次额外移动 | 已消除 |
参阅
构造新的 std::move_only_function 对象 ( std::move_only_function 的公开成员函数) |