std::function<R(Args...)>::function

来自cppreference.com
< cpp‎ | utility‎ | functional‎ | function
 
 
 
函数对象
函数调用
(C++17)(C++23)
恒等函数对象
(C++20)
旧式绑定器与适配器
(C++17 前*)
(C++17 前*)
(C++17 前*)
(C++17 前*)
(C++17 前*)(C++17 前*)(C++17 前*)(C++17 前*)
(C++20 前*)
(C++20 前*)
(C++17 前*)(C++17 前*)
(C++17 前*)(C++17 前*)

(C++17 前*)
(C++17 前*)(C++17 前*)(C++17 前*)(C++17 前*)
(C++20 前*)
(C++20 前*)
 
 
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,

          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

1,2) 构造std::function
3)other目标复制到 *this 的目标。
如果 other 为空,那么 *this 在构造完成时也为空。
4)other 的目标移动到 *this 的目标。
如果 other 为空,那么 *this 在构造完成时也为空。
构造完成时 other 处于有效但未指定的状态。
5)std::forward<F>(f) 初始化目标。目标的类型是 std::decay<F>::type
如果 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 前)
5,10) 如果 f 是函数指针或 std::reference_wrapper,那么不抛异常,否则可能抛出 std::bad_alloc 或存储的可调用对象的复制构造函数所抛的任何异常。

注解

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 2132C++11重载 (5,10) 可能有歧义已约束
LWG 2774C++11重载 (5,10) 会进行一次额外移动已消除

参阅

构造新的 std::move_only_function 对象
(std::move_only_function 的公开成员函数)