【发布时间】:2025-12-05 12:45:01
【问题描述】:
考虑一下这个相当无用的程序:
#include <iostream>
int main(int argc, char* argv[]) {
int a = 5;
auto it = [&](auto self) {
return [&](auto b) {
std::cout << (a + b) << std::endl;
return self(self);
};
};
it(it)(4)(6)(42)(77)(999);
}
基本上,我们正在尝试创建一个返回自身的 lambda。
- MSVC 编译程序,然后运行
- gcc 编译程序,出现段错误
- clang 拒绝程序并显示一条消息:
error: function 'operator()<(lambda at lam.cpp:6:13)>' with deduced return type cannot be used before it is defined
哪个编译器是正确的?是否存在静态约束违规、UB 或两者都没有?
更新这个轻微的修改被clang接受:
auto it = [&](auto& self, auto b) {
std::cout << (a + b) << std::endl;
return [&](auto p) { return self(self,p); };
};
it(it,4)(6)(42)(77)(999);
更新 2:我了解如何编写一个返回自身的函子,或者如何使用 Y 组合子来实现这一点。这更像是一个语言律师问题。
更新 3:问题是不是 lambda 通常返回自身是否合法,而是关于这种特定方式的合法性。
【问题讨论】:
-
clang 此刻看起来更体面,我想知道这样的构造是否甚至可以进行类型检查,更有可能它最终会出现在无限树中。
-
您询问是否合法,这表示这是一个语言律师问题,但有几个答案并没有真正采用这种方法......正确使用标签很重要
-
@ShafikYaghmour 谢谢,加了标签
-
@ArneVogel 是的,更新后的使用
auto& self消除了悬空引用问题。 -
@TheGreatDuck C++ lambda 并不是真正的理论上的 lambda 表达式。 C++ 有内置的递归 types 原始的简单类型 lambda 演算无法表达,因此它可以具有与 a: a->a 和其他不可能的构造同构的东西。
标签: c++ lambda language-lawyer c++17 auto