• 【c++】std::function


    std::function 和 Lambda

    std::function

    std::function 是一个类型擦除对象。这意味着它擦除了某些操作的详细细节,并为它们提供了一个统一的运行时接口。对于 std::function,主要的操作包括复制/移动、销毁,以及通过 operator()(即“类似函数的调用运算符”)进行 ‘调用’。详细的文档

    用更简洁的英语来说,这意味着 std::function 可以包含几乎任何像函数指针一样调用的对象。

    它所支持的签名位于尖括号内:std::function 表示不带参数并返回 void 的函数。std::function 表示带有两个 int 参数并返回 double 的函数。通常,std::function 支持存储任何类似函数的对象,其参数可以从其参数列表进行转换,其返回值可以转换为其返回值。

    重要的是要知道,std::function 和 Lambda 是不同的东西,尽管它们可能是兼容的。

    接下来的代码是一个 Lambda 表达式。这是 C++11 中的新语法,用于编写类似函数的简单对象,即可以用 () 调用的对象。这些对象可以进行类型擦除并存储在 std::function 中,但会带来一些运行时开销。

    如何判定两个std::function 对象是否相等?可以看一个demo

    auto callback1 = []() {std::cout << "Device Change1!\n"; };
    auto callback2 = []() {std::cout << "Device Change2!\n"; };
    auto callback3 = []() {std::cout << "Device Change3!\n"; };
    std::function<void()> func1 = callback1;
    std::function<void()> func2 = callback2;
    std::function<void()> func3 = callback3;
    
    std::cout << "callback1 target_type: " << func1.target_type().name() << std::endl;
    std::cout << "callback2 target_type: " << func2.target_type().name() << std::endl;
    std::cout << "callback3 target_type: " << func3.target_type().name() << std::endl;
    std::cout << "callback3 == callback2: " << int(callback2 == callback3) << std::endl;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    输出:

    callback1 target_type: class 
    callback2 target_type: class 
    callback3 target_type: class 
    callback3 == callback2: 0
    
    • 1
    • 2
    • 3
    • 4

    所以std::function 并没有实现 ==, 可以通过 target_type 来对比每个 std::function 的类型。这种方式是不是只适合于Lambda表达式呢?再验证一下。

    void fnCallback1() {
        std::cout << "callback1 \n";
    }
    
    void fnCallback2() {
        std::cout << "callback2 \n";
    }
    
    std::function<void()> func1 = fnCallback1;
    std::function<void()> func2 = fnCallback2;
    
    
    std::cout << "callback1 target_type: " << func1.target_type().name() << std::endl;
    std::cout << "callback2 target_type: " << func2.target_type().name() << std::endl;
    std::cout << "callback3 == callback2: " << int(fnCallback1 == fnCallback2) << std::endl;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    Lambda

    [](){ code } 特别是一个非常简单的 Lambda。它对应于以下形式:

    struct some_anonymous_type {
      some_anonymous_type() {}
      void operator()const{
        code
      }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    所以Lambda 表达式就是重载了 () 的操作符吗?

    Lambda 的一般形式

    [ capture_list ]( argument_list )
    -> return_type optional_mutable
    {
      code
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    更加一般的内部形式

    struct some_anonymous_type {
      // capture_list turned into member variables
      some_anonymous_type( /* capture_list turned into arguments */ ):
        /* member variables initialized */
      {}
      return_type operator()( argument_list ) const {
        code
      }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • 相关阅读:
    文本溢出 右侧对齐 左侧显示省略号
    力扣(LeetCode)844. 比较含退格的字符串(C语言)
    分享一个基于asp.net的供销社农产品商品销售系统的设计与实现(源码调试 lw开题报告ppt)
    nacos安装详细教程-单机、集群(nginx)
    概率论的一些知识
    外网系统怎么访问协同oa?快解析内网端口映射公网
    stm32HAL库-GPIO
    HBase表的RowKey设计、热点和二级索引
    ShowLayoutAlias...
    奉劝那些刚参加工作的学弟学妹们:要想进大厂,这些核心技能是你必须要掌握的!完整学习路线!
  • 原文地址:https://blog.csdn.net/qq_30340349/article/details/134441481