C++回调函数与匿名函数例子

这里写自定义目录标题

  • C++使用回调函数
    • typedef 定义回调函数
    • std::function定义回调函数
  • C++使用匿名函数
    • Lambda 语法分析
      • 函数对象参数
      • 操作符重载函数参数
      • mutable 或 exception 声明
      • 返回值类型
      • 函数体
    • 示例
  • auto 定义匿名函数

C++使用回调函数

typedef 定义回调函数

typedef void (*callback)(int i);

std::function定义回调函数

using callback = std::function<void(int)>;

C++使用匿名函数

[函数对象参数] (操作符重载函数参数) mutable 或 exception 声明 -> 返回值类型 {函数体}

可以看到,Lambda 主要分为五个部分:[函数对象参数]、(操作符重载函数参数)、mutable 或 exception 声明、-> 返回值类型、{函数体}.

Lambda 语法分析

函数对象参数

标识一个 Lambda 表达式的开始,这部分必须存在,不能省略。函数对象参数是传递给编译器自动生成的函数对象类的构造
函数的。函数对象参数只能使用那些到定义 Lambda 为止时 Lambda 所在作用范围内可见的局部变量(包括 Lambda 所在类
的 this)。函数对象参数有以下形式:

  • 空。没有任何函数对象参数。
  • =。函数体内可以使用 Lambda 所在范围内所有可见的局部变量(包括 Lambda 所在类的 this),并且是值传递方式(相
    当于编译器自动为我们按值传递了所有局部变量)。
  • &。函数体内可以使用 Lambda 所在范围内所有可见的局部变量(包括 Lambda 所在类的 this),并且是引用传递方式
    (相当于是编译器自动为我们按引用传递了所有局部变量)。
  • this。函数体内可以使用 Lambda 所在类中的成员变量。
  • a。将 a 按值进行传递。按值进行传递时,函数体内不能修改传递进来的 a 的拷贝,因为默认情况下函数是 const 的,要
    修改传递进来的拷贝,可以添加 mutable 修饰符。
  • &a。将 a 按引用进行传递。
  • a,&b。将 a 按值传递,b 按引用进行传递。
  • =,&a,&b。除 a 和 b 按引用进行传递外,其他参数都按值进行传递。
  • &,a,b。除 a 和 b 按值进行传递外,其他参数都按引用进行传递。

操作符重载函数参数

标识重载的 () 操作符的参数,没有参数时,这部分可以省略。参数可以通过按值(如: (a, b))和按引用 (如: (&a, &b)) 两种
方式进行传递。

mutable 或 exception 声明

这部分可以省略。按值传递函数对象参数时,加上 mutable 修饰符后,可以修改传递进来的拷贝(注意是能修改拷贝,而不是
值本身)。exception 声明用于指定函数抛出的异常,如抛出整数类型的异常,可以使用 throw(int)。

返回值类型

标识函数返回值的类型,当返回值为 void,或者函数体中只有一处 return 的地方(此时编译器可以自动推断出返回值类型)
时,这部分可以省略。

函数体

标识函数的实现,这部分不能省略,但函数体可以为空。

示例

[] (int x, int y) { return x + y; } // 隐式返回类型
[] (int& x) { ++x;  } // 没有 return 语句 -> Lambda 函数的返回类型是 'void'
[] () { ++global_x;  } // 没有参数,仅访问某个全局变量
[] { ++global_x; } // 与上一个相同,省略了 (操作符重载函数参数)

可以像下面这样显示指定返回类型:

[] (int x, int y) -> int { int z = x + y; return z; }

在这个例子中创建了一个临时变量 z 来存储中间值。和普通函数一样,这个中间值不会保存到下次调用。什么也不返回的
Lambda 函数可以省略返回类型,而不需要使用 -> void 形式。

auto 定义匿名函数

#include
using namespace std;

using testfunc = std::function;
int test(testfunc func) {
    return func(3);
}
int main()
{
    int a = 1;
    int b = 2;
    
    auto func = [=, &b](int c)->int {
        return b += a + c;
    };
    int c = test(func);
    printf(" a %d b %d c %d\n", a, b, c);
    return 0;
}

说明:

  • 如果函数对象参数中包含了=,后面的参数必须要用& ,否则 会打印如下错误
test.cpp:14:21: error: '&' must precede a capture when the capture default is '='
    auto func = [=, b](int c) mutable ->int {
  • 记住加muteable的情况,记住默认是值传递 ,并带有const
 14     auto func = [a, b](int c) ->int {
 15         return b += a + c;
 16     };

编译的时候会报如下错
test.cpp:15:18: error: cannot assign to a variable captured by copy in a non-mutable lambda
        return b += a + c;

#参考
blog 季末的天堂

你可能感兴趣的:(C/C++,c++)