8. C++ function的介绍和使用

发布时间:2024年01月03日
std::function的介绍和使用

std::function是一个可变参类模板,是一个通用的函数包装器(Polymorphic function wrapper)。std::function的实例可以存储、复制和调用任何可复制构造的可调用目标,包括普通函数、成员函数、类对象(重载了operator()的类的对象)、Lambda表达式等。是对C++现有的可调用实体的一种类型安全的包裹(相比而言,函数指针这种可调用实体,是类型不安全的)。

std::function中存储的可调用对象被称之为std::function的目标。若std::function中不含目标,调用不含目标的std::function会抛出std::bad_function_call 异常。

看到这里我们一定会疑惑,std::function到底怎么将可调用目标存储起来的?怎么为不同可调用目标提供通用的“包装”?

我们将这些疑问暂时放下,先看一下如何使用std::function。

std::function源码分析

std::function模板类的定义如下,有一个标准函数指针类型的成员变量_M_invoker。

std::function涉及到的几个类之间的简化关系:

图片

  • function的函数指针成员变量_M_invoker被初始化为_Function_handler的成员函数_M_invoker;_M_invoker调用了接管的可调用对象;

    • 四个特化版本均继承自_Function_base::_Base_manager。

    • 其中第一个和第二个特化版本存储的可调用目标是普通函数、类实例或者Lambda表达式,两个特化版本的区别为第一个存储的可调用目标有返回值,第二个存储的可调用目标没有返回值

    • 其中第三个和第四个特化版本存储的可调用目标是类的成员函数,区别在于成员函数是否有返回值。

    • 每一个特化版本均包含一个静态函数_M_invoke,使用该函数初始化function::_M_invoker,在该函数中完成可调用目标的调用。

  • function的基类_Function_base的成员_M_functor真正接管可调用对象,当可调用对象的大小大于两个指针时存储在堆上,_M_functor指向存储位置;

    • 所以当接管的可调用对象的大小大于2个指针大小时,就会动态分配内存。否则就会直接使用_M_pod_data作为存储空间,直接存储可调用对象。
    • 普通函数指针的大小为一个指针大小,类成员函数指针的大小为2个指针,Lambda表达式、类对象的大小均有可能大于一个指针大小,甚至大于两个指针大小,取决于其成员变量的数量。
  • _Function_base的内部类_Base_manager提供接口函数。

ase的内部类_Base_manager提供接口函数。**

文章来源:https://blog.csdn.net/weixin_46645965/article/details/135354986
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。