可调用对象 | 青训营笔记

72 阅读1分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第4天

如果一个对象可以使用调用运算符"()", ()里面可以放参数,这个对象就是可调用对象。

常见可调用对象:

函数:

using PF = void (*)(int);

void test(int i) {

       std::cout << "i:" << i << std::endl;

}

void func(PF pf, int i) {

       pf(i);

}

int main(int argc, char* argv[]) {

       func(test, 10);

       return 0;

}

仿函数:

有operator()函数的类对象, 可以当作函数使用 ,即把()重载了

当成重载函数理解

class T {
public:
       void operator()(int x) {
              cout << "x:" << x << endl;
       }
};

int main(int argc, char* argv[]) {
       T t;
       t(20);    //这里类对象t可以装参数
       return 0;
}

lambda表达式:

就是匿名函数,C++提供了lambda表达式,需要函数时直接在需要的地方写一个lambda表达式,省去了定义函数的过程,提高效率

C++里lambda大量使用

lambda表达式的格式:

最少是“[] {}”,完整的格式为“auto ret = [] () -> 类型{}()”

一个简单的lambda

[](int i){
    std::cout<<i<<std::endl;
}(10);

完整的lambda

int pre = 10;
int a = 2;
int ret = [pre](int i) -> int {
    i = i + pre;
    return i;
}(a);

cout << ret << endl;

//另一种使用方式

auto ret = [pre](int i) -> int {    //写auto ,不然类型太长
i = i + pre;
return i;
};
cout << ret(a) << endl;

lambda各个组件介绍

  1. []代表捕获列表:表示lambda表达式可以访问前文的哪些变量。

    1). []表示不捕获任何变量。 

    2). [=]:表示按值捕获所有变量。

    3). [&]:表示按引用捕获所有变量。

    =,&也可以混合使用,比如

      1.[=, &i]:表示变量i用引用传递,除i的所有变量用值传递。

      2.[&, i]:表示变量i用值传递,除i的所有变量用引用传递。

    当然,也可以捕获单独的变量

      1.[i]:表示以值传递的形式捕获i

      2.[&i]:表示以引用传递的方式捕获i

  1. ()代表lambda表达式的参数,函数有参数,lambda自然也有。

  2. ->ret表示指定lambda的返回值,如果不指定,lambda表达式也会推断出一个返回值的。//没有ruturn 就是void

  3. {}就是函数体了,和普通函数的函数体功能完全相同。

lambda最常见用法, 给普通函数做参数:

using PF = void (*)(int);  //定义一种函数指针
void func(PF pf, int x) {
       pf(x);
}
int main(int argc, char* argv[]) {
       int a = 2;
       int b = 3;
       func([](int i) {  
       //lambda表达式作为函数指针对象,[]必须为空
              std::cout << "i:" << i << std::endl;
              std::cout << "this is lambda" << std::endl;
              }, a);
       return 0;
}

//解决这一问题,C++11

#include<functional>
//和函数指针相同效果
using func_type = std::function<void(int)>;

void func(func_type pf, int x) {
       pf(x);
}

int main(int argc, char* argv[]) {
       int a = 2;
       int b = 3;
       func([b](int i) {
              std::cout << "i:" << i << std::endl;
              std::cout << "b:" << b << std::endl;
              std::cout << "this is lambda" << std::endl;
              }, a);
       return 0;
}