对于C++编译器而言lambda表达式的类型是什么?为何gdb显示为struct?
C++ lambda表达式的编译器实现本质
C++标准中定义lambda是可调用的匿名对象,主流编译器的统一实现逻辑是:lambda表达式本质是编译器自动生成的、独一无二的匿名仿函数(函数对象)。
为什么lambda的类型会被识别为struct
没有任何C++标准强制要求lambda必须用struct实现,这是GCC、Clang、MSVC等所有主流编译器的共同选择,核心原因是struct的特性可以完美匹配lambda的所有设计需求:
- 编译器会为每一个独立的lambda表达式生成一个唯一命名的匿名struct,哪怕两个lambda的参数、返回值、实现逻辑完全相同,对应的struct类型也不互通,这也是lambda类型只能用
auto接收的原因。 - 如果lambda有捕获外部变量,捕获的内容会直接作为这个struct的成员变量存储:值捕获存变量的拷贝,引用捕获存对应变量的引用或指针。
- 编译器会自动为这个struct重载
operator()运算符,运算符的参数列表、返回值、执行逻辑完全和你写的lambda定义一致,这就是lambda可以像普通函数一样调用的底层原因。 - 对于无捕获的空状态lambda,编译器还会额外给这个struct实现普通函数指针的类型转换运算符,这也是无状态lambda可以赋值给对应类型函数指针的原因。
你示例中使用的两个lambda都没有实际捕获外部变量(捕获列表[&]是默认按引用捕获,但lambda内部没有用到任何外部作用域变量,实际属于无状态lambda),所以对应的匿名struct没有任何成员变量,你用gdb的ptype命令才会得到空struct的输出,后缀的<lambda(int)>、<lambda(double)>是编译器给匿名struct加的标识,用来快速区分不同签名的lambda。
内容的提问来源于stack exchange,提问作者Sad egg
相关产品推荐
相关产品推荐

