【c++】std::function

std::function 和 Lambda

std::function

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

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

它所支持的签名位于尖括号内:std::function<void()> 表示不带参数并返回 void 的函数。std::function<double(int, int)> 表示带有两个 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;

输出:

callback1 target_type: class <lambda_821272ba063a97e86c121d7c9c9ed8c6>
callback2 target_type: class <lambda_43458c65006f28841b4c951d4c2e7470>
callback3 target_type: class <lambda_3166a7b70429e7fc88425f8de8d7c79f>
callback3 == callback2: 0

所以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;

Lambda

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

struct some_anonymous_type {
    
    
  some_anonymous_type() {
    
    }
  void operator()const{
    
    
    code
  }
};

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

Lambda 的一般形式

[ capture_list ]( argument_list )
-> return_type optional_mutable
{
    
    
  code
}

更加一般的内部形式

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
  }
};

猜你喜欢

转载自blog.csdn.net/qq_30340349/article/details/134441481