lambada表达式是什么?
详解:lambada表达式详解
我们知道lambada其实是一个匿名函数 ,
它属于 可调用对象 类型。在 C++ 中,lambda 表达式会生成一个隐式定义的类,这个类重载了 operator()
,使得该对象可以像函数一样被调用。
虽然c++标准中lambada表达式并不是一个class,但是我们可以把lambada表达式看作是一个匿名类
检验:
我们通过is_class来判断(这是编译器隐式定义的类,并不代表lambada就是一个class)
#include <iostream>
using namespace std;
int main()
{
int index = 10;
int *p = &index;
auto a = [ ]() {
for (int i = 1; i <= index; i++) {
cout << "hello world" << endl;
}
cout << *p << endl;
};
//cout << sizeof(a) << endl;
if (std::is_class<decltype(a)>::value == true) cout << "yes" << endl;
return 0;
}
运行结果:
lambada表达式的大小
我们已经知道了lambada表达式是一个匿名类,那么我们就可以通过内存对齐来探讨lambada表达式的大小了
无捕获
auto a = []() {};
auto b = [](int k) {};
cout << sizeof(a) << endl; //打印1
cout << sizeof(b) << endl; //打印1
可以看到和形参无关,无捕获参数相当于一个空类的大小
有捕获但未使用
int index = 10;
int *p = &index;
auto a = [=]() {}; //值捕获
auto b = [&]() {}; //引用捕获
cout << sizeof(a) << endl; //打印1
cout << sizeof(b) << endl; //打印1
虽然捕获了外界所有对象但是并未使用,则还是空类的大小
有捕获且使用
#include <iostream>
using namespace std;
int main() {
int index = 10;
int *p = &index;
char ch = 'a';
auto a = [ = ]() {cout << index;};
auto b = [&]() {cout << index;};
auto c = [ = ]() { cout << index << *p << endl;};
auto d = [&]() {cout << index << *p << endl;};
auto e = [&]() {cout << ch << endl;};
cout << sizeof(a) << endl; //值捕获 使用int 打印4
cout << sizeof(b) << endl; //引用捕获 使用int 打印8
cout << sizeof(c) << endl; //值捕获 使用int int* 内存对齐 打印16
cout << sizeof(d) << endl; //引用捕获 使用 int int* 内存对齐 打印16
cout << sizeof(e) << endl; //引用捕获 使用 char 打印 8
return 0;
}
运行结果:
可以看出值捕获是都在我们认知之内,也就是和我们期望的相同。
引用捕获 使用int或者char 竟然也有8个字节 不难想到引用捕获的是地址, 而值捕获是拷贝的副本,
总结
引用捕获:实际是捕获对象的地址 计算大小是 使用参数指针的内存对齐后的大小
值捕获:捕获是拷贝的副本 计算大小时 遵循使用参数的内存对齐后的大小