std::function<R(Args...)>::function
来自 zh.cppreference.net
function() noexcept;
|
(1) | (C++11 起) |
function( std::nullptr_t ) noexcept;
|
(2) | (C++11 起) |
function( const function& other );
|
(3) | (C++11 起) |
function( function&& other );
|
(4) | (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,
std::nullptr_t ) noexcept;
|
(7) | (C++11 起) (C++17 中移除) |
template< class Alloc >
function( std::allocator_arg_t, const Alloc& alloc,
const function& other );
|
(8) | (C++11 起) (C++17 中移除) |
template< class Alloc >
function( std::allocator_arg_t, const Alloc& alloc,
function&& other );
|
(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 的 target 到 *this 的 target。
other 如果 *this 为空,则调用后 other 也为空。调用后 处于有效但未指定的状态。5)
std::forward<F>(f) 用 std::decay<F>::type 初始化 target。目标类型为 。
f 如果 std::function 是空函数指针、空成员指针,或某个 *this 特化的空值,则调用后 为空。此重载仅在满足以下所有条件时参与重载决议:
|
(C++23 起) |
- 类型
std::decay<F>::type的左值能被参数类型Args...调用,并返回类型R。
|
如果 |
(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
的公开成员函数)
|