C/C++编程:lambda表达式

1059 篇文章 285 订阅

面试题目

你怎么用lambda表达式

匿名函数。当我有一个功能,只有一个地方被调用,但是函数很简单,就用lambda表达式

lambda表达式是怎么返回的呢?

使用auto接收,使用尾值返回类型的方式设置lambda表达式的返回类型

int main(){
  auto lam == [](int elem)-> int {return elem};
  cout << lam(3);
}

正文

lambda入门

一个函数内部不能包含另一个函数,lamba表达式解决函数此问题:函数表达式

最简单的lamba表达式

#include <iostream>

using namespace std;

void main()
{
	[] {cout << "hello"; cout << "world"; }();    //匿名lamba表达式,()表示调用,{}表示函数体,

	cin.get();
}

lamba表达式与函数指针

定义一个函数指针,然后调用

#include <iostream>
using namespace std;
void main()
{
	auto fun = [] {cout << "hell"; }; //fun是一个函数指针,指向一个函数
	fun();  //调用
	cin.get();
}

lamba的传入参数

  • 与一般函数一样,有副本机制
#include <iostream>
using namespace std;
void main()
{
	int num = 100;
	auto funrc = [](int num) {num = 5, cout << num << endl; };
	cout << "main:" << num << endl;  //100
	funrc(num);    //5  //函数副本机制
	cout << "main:" << num << endl;  //100
	cin.get();
}

lamba表达式的返回值

#include <iostream>
using namespace std;
int  main()
{
    auto fun1 = [](double a, double b) {return a + b; };  //有名lamba表达式,auto自动推理类型
    cout << fun1(11, 11.1) << endl;

    auto fun2 = [](double a, double b)->int {return a + b; }; //->指定返回值类型
    cout << fun2(10, 19.1) << endl;

    auto fun3 = [](double a, double b)->decltype(a + b) {return a + b; }; //->指定返回值类型
    cout << fun3(10, 10) << endl;

   // cout << typeid(fun1).name() << endl;  //class <lambda_随机数>
   // cout << (void*)fun1 << endl; //lamba表达式是内联展开的,无法取出地址

    
    cin.get();
}

总结:

  • lamba表达式是为了解决函数怀孕问题
  • lamba表达式是内联展开的,无法取出地址
  • lamba本质上是一个类
  • lamba()的传入参数有副本机制

auto自动推理数据类型

#include <iostream>

using namespace std;


void main()
{
	[](auto a, auto b){cout << a + b << endl; }(10, 11);  //auto可以推理数据类型
	[](auto a, auto b){cout << a + b << endl; }(10.8, 11);
	[](auto a = 0 , auto b =  0 ){cout << a + b << endl; }(10, 11); 
	cin.get();
}

lambda高级

lamba表达式如何捕获外部变量

  • &表示以引用的方式捕获外部变量,因此可以直接对外部变量内存进行读写
  • =表示以值传递的方式捕获外部变量,因此不能改变外部变量,matable是对=的补充
  • 必须显示的捕获,没有隐式的捕获
#include <iostream>

using namespace std;

int  main()
{
    int num1 = 100;
    int num2 = 99;

    cout << "原本:                                                     "<< &num1 <<"[" <<num1  << "], "<< &num2 <<"[" << num2 << "]"<< endl;

    [=]() {
        cout  << "[=]()        可以捕获外部变量生成一个副本,这个副本是只读的:     "<< &num1 <<"[" <<num1  << "], "<< &num2 <<"[" << num2 << "](副本是只读的)\n";
    }();  //=只能读不能写   ---> 两个地址不同,说明是不同的内存,=的操作是复制原本给lamba表达式

    // [=]() {num1 = 22, cout << num1 << num2 << endl; }();//    C3491    “num1” : 无法在非可变 lambda 中修改通过复制捕获    
    [=]()mutable {
        num1 = 666; num2 = 77;
        cout <<"[=]()mutable 可以使用mutable生成一个副本,这个副本是可读可写的:  " << &num1 <<"[" <<num1  << "], "<< &num2 <<"[" << num2 << "](修改副本不会影响原本:mutalbe是一个声明,表示操作副本,可以看作是=的补充)\n";
    }(); //666999mutable改变副本  ----> mutalbe是一个声明,表示操作副本,可以看作是=的补充

        cout << "原本:                                                     "<< &num1 <<"[" <<num1  << "], "<< &num2 <<"[" << num2 << "]"<< endl;

    num1 = 100, num2 = 99;
    [&]() {
        num1 = 11, num2 = 66, cout << "[&]          可以捕获并读写外部变量的原本                      "<< &num1 <<"[" <<num1  << "], "<< &num2 <<"[" << num2 << "](&地址相同,表示以引用的方式捕获外部变量,操作同一块内存,因此可以改写原本)\n";
    }();  //1199   &表示读写外部变量,改变原本  ---->  &地址相同,表示以引用的方式捕获外部变量,操作同一块内存,因此可以改写原本
    cout << "原本:                                                     "<< &num1 <<"[" <<num1  << "], "<< &num2 <<"[" << num2 << "]"<< endl;

    num1 = 100, num2 = 99;
}

单独改变捕获某一个值

#include <iostream>

using namespace std;


int  main()
{
    int a = 10;
    int b = 9;
    int c = 15;

    //[&a]() {a = 100;  cout << a << b << c << endl; }();  //无法隐式捕获“b/c”,因为尚未指定默认捕获模式,	封闭函数局部变量不能在 lambda 体中引用,除非其位于捕获列表中
    [&a, b, c]() {a = 100;  cout   << "     " <<a << "   " << b << "   " << c  << "   " << endl; }();  //可以改变a的原本
    cout << "原本: "<< a << "   " << b << "   " << c  << "   " << endl;

    a = 10; b = 9; c = 15;
    [a, b, c]()mutable {a = 999; b = 333;  cout   << "     " <<a << "   "<< b << "   " << c << "\n"; }();  //999 333  15
    cout << "原本: "<< a << "   " << b << "   " << c  << "   " << endl;

    //[]()mutable {a = 999; b = 333; cout << a << "   " << b << "   " << c; }(); //封闭函数局部变量不能在 lambda 体中引用,除非其位于捕获列表中	Cpp.cpp	e : \C++\Cpp.cpp\Cpp.cpp\类型转换.cpp	15

}

lamba表达式与数组

#include <iostream>
#include <array>
#include <algorithm>

using namespace std;

void main()
{
	array<int, 10>myint{ 1, 2, 3, 4, 5, 6, 7 };
	for_each(myint.begin(), myint.end(), [](int num) {cout << num << "   ";  });  //显示 1, 2, 3, 4, 5, 6, 7 0 0 0
	cout << "\n";
	for_each(myint.begin(), myint.end(), [](int num) {num += 1, cout << num << "   "; }); //修改副本,函数传参副本机制,因此修改的是副本
	cout << "\n";
	for_each(myint.begin(), myint.end(), [](int num) {cout << num << "   ";  });  //显示 1, 2, 3, 4, 5, 6, 7 0 0 0
	cout << "\n      *******************\n"  ;

	for_each(myint.begin(), myint.end(), [](int &num) {num += 1, cout << num << "   "; }); //修改原本,引用原本,对原本进行操作,因此会修改原本
	cout << "\n";
	for_each(myint.begin(), myint.end(), [](int num) {cout << num << "   ";  });  //显示,2,3,4,5,6,7,8,1,1,1
	cin.get();
}

总结:

  • 函数传参如果是值传递,那么副本机制修改副本;如果是引用传参,那么操作原本
  • lamba表达式是为了解决代码内嵌问题
  • [](){}()匿名lamba表达式
  • for_each常常用来遍历容器,比如数组
  • array<int, n>{0};是CPP风格的数组
  • lamba表达式中[=]表示值捕获外部遍历,[&]表示引用捕获。

--

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值