C++函数对象-函数包装器-(std::function)(一)- 构造新的 std::function 实例 - 析构 std::function 实例

任何定义了函数调用操作符的对象都是函数对象。C++ 支持创建、操作新的函数对象,同时也提供了许多内置的函数对象。


函数包装器

std::function 提供存储任意类型函数对象的支持。

包装具有指定函数调用签名的任意类型的可调用对象

std::function

template< class >
class function; /* 不定义 */

(C++11 起)

template< class R, class... Args >
class function<R(Args...)>;

(C++11 起)

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

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

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

成员类型

类型定义
result_typeR
argument_type(C++17 中弃用)(C++20 中移除)若 sizeof...(Args)==1 且 TArgs... 中首个且唯一的类型,则为 T
first_argument_type(C++17 中弃用)(C++20 中移除)若 sizeof...(Args)==2 且 T1Args... 中二个类型的第一个,则为 T1
second_argument_type(C++17 中弃用)(C++20 中移除)若 sizeof...(Args)==2 且 T2Args... 中二个类型的第二个,则为 T2


​​​​​​​构造新的 std::function 实例

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

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

1-2) 构造 function

3-4) 复制 (3) 或移动 (4) other目标到 *this 的目标。若 other,则调用后 *this 将亦为。对于 (4) , other 在调用后处于合法但未指定的状态。

5) 以 std::move(f) 初始化目标。若 f 是空指针或指向成员的空指针,则 *this 在此调用后将为。此构造函数不参与重载决议,除非 f 对于参数类型 Args... 和返回类型 R 可调用 (Callable) 。 (C++14 起)

6-10) 同 (1-5) ,除了将 alloc 用于分配任何 function 会用到的内部数据结构的内存。

目标是函数指针或 std::reference_wrapper 时,保证使用小对象优化,即始终直接存储这些目标于 std::function 对象中,不发生动态内存分配。可以构造其他大对象于动态分配的存储中,并由 std::function 对象通过指针访问。

参数

other-用于初始化 *this 的函数对象
f-用于初始化 *this 的可调用对象
alloc-用于内部内存分配的分配器 (Allocator)
类型要求
- F 必须满足可调用 (Callable) 和 可复制构造 (CopyConstructible) 的要求。
- 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 中移除了分配器支持。

析构 std::function 实例 

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

~function();

(C++11 起)

销毁 std::function 实例。若 std::function,则亦销毁其目标

调用示例

#include <iostream>
#include <functional>

int main()
{
    std::cout << std::boolalpha;
    //从各种资源构造 std::function 。
    //1 - 2) 构造空 function 。
    std::function<void(void)> function1;
    std::function<void(void)> function2(std::nullptr_t);
    std::function<bool(int)> function3;
    std::function<bool(int)> function4(std::nullptr_t);

    //3 - 4) 复制(3) 或移动(4) other 的目标到 *this 的目标。
    //若 other 为空,则调用后 *this 将亦为空。对于(4) , other 在调用后处于合法但未指定的状态。
    std::function<bool(int)> function5 = [](int num)
    {
        return num % 2 == 0;
    };
    std::cout << typeid(function5).name() << "  function5(1024): " << function5(1024) << std::endl;
    std::function<bool(int)> function6(function5);
    std::cout << typeid(function6).name() << "  function6(1023): " << function6(1023) << std::endl;
    std::function<bool(int)> function7(std::move(function5));
    std::cout << typeid(function7).name() << "  function7(1023): " << function7(1023) << std::endl;
    std::cout << typeid(function5).name() << "  function5 bool : " << (function5 ? true : false) << std::endl;
    
    //5) 以 std::move(f) 初始化目标。若 f 是空指针或指向成员的空指针,则 *this 在此调用后将为空。
    //此构造函数不参与重载决议,除非 f 对于参数类型 Args... 和返回类型 R 可调用(Callable) 。(C++14 起)
    auto function8 = [](int num)
    {
        return num % 2 == 1;
    };
    std::function<bool(int)> function9(function8);
    std::cout << typeid(function8).name() << "  function8(1023): " << function8(1023) << std::endl;
    std::cout << typeid(function9).name() << "  function9(1023): " << function9(1023) << std::endl;

    return 0;
}

输出

St8functionIFbiEE  function5(1024): true
St8functionIFbiEE  function6(1023): false
St8functionIFbiEE  function7(1023): false
St8functionIFbiEE  function5 bool : false
Z4mainEUliE0_  function8(1023): true
St8functionIFbiEE  function9(1023): true

  • 41
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值