这几天写算法题时看见灵神的以下代码
1. 第一种写法:C++23 显式对象参数 (Deducing this)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| auto dfs = [](this auto&& self, TreeNode* node) -> int { if (!node) return 0; return 1 + self(node->left) + self(node->right); };
int result = dfs(root); ```
**机制**:这里的 self 代表的是 Lambda 闭包对象本身。这是一种编译时推导。 性能优势: **零开销**:这是纯粹的编译时行为,dfs 是一个原始的 Lambda 匿名类对象。 **内联优化**:编译器完全知道 self 的具体类型,因此可以极大地进行内联优化,递归效率远高于 std::function。 **解耦**:Lambda 不再需要捕获自己(实际上 Lambda 也无法直接捕获自己),它是通过参数传递实现自引用的 在lamada函数中,写递归函数在C++23前是比较麻烦的,且有性能问题 ### 2. 第二种写法:传统的包装器递归 (std::function)
```c++ std::function<int(TreeNode*)> dfs = [&dfs](TreeNode* node) -> int { if (!node) return 0; return 1 + dfs(node->left) + self(node->right); };
|
机制:std::function 是一个重量级的**类型擦除(Type Erasure)**容器。它在堆上分配空间(通常情况下),并持有一个函数指针或 Lambda 闭包。
性能开销:
间接调用:每次递归都会产生通过函数指针调用的开销,编译器很难对其进行内联(Inline)优化。
动态内存:std::function 可能涉及动态内存分配。
局限性:必须显式声明函数签名,且依赖外部变量名的捕获,容易产生生命周期风险。