为什么要编写一个带有名称的 C++ lambda,以便可以从某处调用它?

问题描述 投票:0回答:8

为什么要编写一个带有名称的 C++ lambda,以便可以从某个地方调用它?这不会违背 lambda 的初衷吗?在那里写一个函数更好吗?如果没有,为什么?函数会有什么缺点吗?

function c++11 lambda
8个回答
13
投票

它的一个用途是让函数访问封闭的范围。

在 C++ 中,我们没有像其他语言那样的嵌套函数。 使用命名的 lambda 可以解决这个问题。 一个例子:

#include <iostream>

int main ()
{
    int x;

    auto fun = [&] (int y) {
        return x + y;
    };

    std::cin >> x;

    int t;
    std::cin >> t;
    std::cout << fun (fun (t));
    return 0;
}

这里,函数

fun
基本上是
main
中的嵌套函数,能够访问其局部变量。 我们可以对其进行格式化,使其类似于常规函数,并多次使用它。


10
投票

使用名称的一个很好的理由是表达意图。然后我们可以检查 lambda 是否做了“正确的事情”,并且读者可以检查意图。给定:

std::string key;
std::map<std::string, int> v;

可以写出以下内容:

std::find_if( v.begin(), v.end(), [&](auto const& elem){ return elem.first == key; } );

但很难判断它是否做了“正确的事”。而如果我们拼写出来:

auto matches_key = [&](auto const& elem){ return elem.first == key; };

std::find_if( v.begin(), v.end(), matches_key );

更清楚的是,我们确实希望进行相等比较,并且提高可读性。


6
投票

在命名 lamdba 和自由函数之间进行选择时,我认为需要考虑三件事:

  1. 您需要来自周围范围的变量吗?如果是,请选择 lamdba 并利用其闭包。否则,请使用免费函数(因为 3.)。
  2. 闭包状态是否可以同样好地作为函数参数传递?如果是,请考虑选择免费函数(因为 3)。
  3. 您想为可调用对象编写测试和/或在多个翻译单元中重用它吗?如果是,请选择一个自由函数,因为您必须在头文件中声明它并在 lamdba 闭包中捕获变量

    • 在头文件中有点混乱(当然,这是有争议的)。

    • 要求已知类型。因此,您不能接受函数参数和返回类型的前向声明来减少编译时间。


3
投票

当你的 lambda 本身就是一个递归函数时,你别无选择,只能给它一个名字。此外,

auto
关键字是不够的,您必须使用带有返回类型和参数列表的
std::function
来声明它。

下面是返回第 N 个斐波那契数的函数示例:

std::function<int(int)> fibonacci = [&](int n) {
    if (n == 0 || n == 1) {
        return 1;
    } else {
        return fibonacci(n - 1) + fibonacci(n - 2);
    }
}

您必须为其指定名称才能使用

&
捕获它。并且
auto
不起作用,因为 lambda 在调用自身之前需要知道它的类型。


1
投票

这基本上是一个基于意见的问题。这取决于您,无论您喜欢函数还是 lambda,它们都是等效的。当您需要来自周围环境的变量时,lambda 就会发挥作用。您只需捕获它们,而不是将其作为参数传递,这很简洁。

但除此之外,没有什么区别。


1
投票

在调整 C++ 应用程序时,与匿名/未命名 lambda 相比,命名 lambda 更容易调整/跟踪


0
投票

我一直认为 lamda 是一件好事——在引入 lamda 之前,我在没有它们的情况下进行了大量的 C++ 编码。因此,在某些方面,我认为围绕它们没有太多应该或不应该的事情。它们可以使用,但可以让您的生活更轻松。

有一次我使用命名的 lamdas 来限定一个函数的范围 - 即 lamda 只会在另一个函数中使用 - 也许它会做一些有点危险的事情,你不希望其他函数访问或者你可能不希望不想污染命名空间。

如果你的 lamda 太长而无法成为简单的单行文字,但你又不希望它成为 如果您的范围之外可用,那么命名的 lamda 是生成整洁且易于阅读的代码的理想方法。


0
投票

当对一个方法的多次调用使用相同的 lambda 时,您需要按名称引用它。

© www.soinside.com 2019 - 2024. All rights reserved.