# std::function

< cpp‎ | utility‎ | functional

定义于头文件 `<functional>` |  |
template< class > class function; /* 未定义 */ |  | (C++11 起)
template< class R, class... Args > class function<R(Args...)>; |  | (C++11 起)

类模板 `std::function` 是通用多态函数包装器。 `std::function` 的实例能存储、复制及调用任何可复制构造 (CopyConstructible) 的可调用 (Callable) 目标——函数、 lambda 表达式、 bind 表达式或其他函数对象，还有指向成员函数指针和指向数据成员指针。

存储的可调用对象被称为 `std::function` 的目标。若 `std::function` 不含目标，则称它为空。调用空 `std::function` 的目标导致抛出 std::bad_function_call 异常。

`std::function` 满足可复制构造 (CopyConstructible) 和可复制赋值 (CopyAssignable) 。

### 成员类型

类型 | 定义
`result_type` | `R`
`argument_type`(C++17 中弃用)(C++20 中移除) | 若 sizeof...(Args)==1 且 `T` 是 `Args...` 中首个且唯一的类型，则为 `T`
`first_argument_type`(C++17 中弃用)(C++20 中移除) | 若 sizeof...(Args)==2 且 `T1` 是 `Args...` 中二个类型的第一个，则为 `T1`
`second_argument_type`(C++17 中弃用)(C++20 中移除) | 若 sizeof...(Args)==2 且 `T2` 是 `Args...` 中二个类型的第二个，则为 `T2`

### 成员函数

(构造函数) | 构造新的 std::function 实例 (公开成员函数)
(析构函数) | 析构 std::function 实例 (公开成员函数)
operator= | 为内容赋值 (公开成员函数)
swap | 交换内容 (公开成员函数)
assign (C++17 中移除) | 为内容赋值一个新的目标 (公开成员函数)
operator bool | 检查是否包含了有效的目标 (公开成员函数)
operator() | 调用其目标 (公开成员函数)
##### 目标访问
target_type | 获得 std::function 所存储的目标的typeid (公开成员函数)
target | 获得指向 std::function 所存储的目标的指针 (公开成员函数)

### 非成员函数

std::swap(std::function) (C++11) | 特化 std::swap 算法 (函数模板)
operator==operator!= (C++20 中移除) | 比较 std::function 和 nullptr (函数模板)

### 辅助类

std::uses_allocator<std::function> (C++11) (C++17 前) | 特化 std::uses_allocator 类型特性 (类模板特化)

### 推导指引(C++17 起)

### 注解

当结果类型为引用的 `std::function` 从无尾随返回类型的 lambda 表达式初始化时需要留心。由于 auto 推导的起效方式，这种 lambda 表达式将始终返回纯右值。故而结果引用将始终绑定到生命期在 `std::function::operator()` 返回时结束的临时量。

    std::function<const int&()> F([]{ return 42; });
    int x = F(); // 未定义行为： F() 的结果是悬垂引用

### 示例

    #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);

        // 存储 lambda
        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) {
            // 存储 lambda 对象以模拟“递归 lambda ”，注意额外开销
            std::function<int(int)> fac = [&](int n){ return (n < 2) ? 1 : n*fac(n-1); };
            // note that "auto fac = [&](int n){...};" does not work in recursive calls
            return fac(n);
        };
        for (int i{5}; i != 8; ++i) { std::cout << i << "! = " << factorial(i) << ";  "; }
    }

可能的输出：

    -9
    42
    31337
    314160
    314160
    num_: 314159
    314161
    314162
    18
    5! = 120;  6! = 720;  7! = 5040;

### 参阅

move_only_function (C++23) | 包装具有指定函数调用签名的任意类型的可调用对象 (类模板)
bad_function_call (C++11) | 调用空的 std::function 时抛出的异常 (类)
mem_fn (C++11) | 从成员指针创建出函数对象 (函数模板)