C++11 lambda函数 - 如何传递参数

22

我之前使用了lambda函数来传递给std::condition_variable的wait()函数,但事实并非如此。 我使用的是不带任何参数的lambda函数,对我而言一切都很清晰。 但我完全不明白如何使用具有参数列表的lambda函数。 如何使用带参数的lambda函数? 如何向它们传递参数?


2
任何关于Lambda的资源都会解释如何使它们接受参数。 - chris
@chris我知道如何编写带有参数的lambda表达式 - [](int parameter) {lambda body},但是我该如何使用这个lambda呢? - Littlebitter
1
就像一个函数。 - chris
@chris 我曾经困惑于lambda没有名称,下面的答案帮助了我。 - Littlebitter
3个回答

33

如何使用带有参数的lambda表达式?如何向它们传递参数?

它的使用方式与任何其他可调用对象一样:

#include <iostream>

int main()
{
    auto l = [] (int i) { std::cout << "The answer is " << i; };
    l(42);
}

还要注意,您无需将lambda表达式存储在变量中以调用它。以下是重写上述程序的另一种替代方法:

#include <iostream>

int main()
{
    [] (int i) { std::cout << "The answer is " << i; } (42);
    //                                                 ^^^^
    //                                 Invoked immediately!
}

lambda函数的类型(也称为“lambda闭包”)由编译器定义,并且是一个带有调用运算符的函数对象,其签名与您在定义lambda时指定的签名相同。因此,您可以像调用函数或可调用对象一样调用lambda函数。

因此,如果您想将lambda分配给对象,则最佳实践是使用auto让编译器推断其类型。如果您不想或无法使用auto,则可以:

  1. 对于非捕获的lambda函数,使用函数指针(捕获的lambda函数不能转换为函数指针)。因此,在上述情况下,以下内容也有效:

    #include <iostream>
    
    int main()
    {
        void (*f)(int) = [] (int i) { std::cout << "The answer is " << i; };
        f(42);
    }
    
  2. 使用 std::function(即使 lambda 表达式有捕获也始终可行):

  3. #include <iostream>
    #include <functional>
    
    int main()
    {
        std::function<void(int)> f = [] (int i) 
                                   { std::cout << "The answer is " << i; };
        f(42);
    }
    

5
auto lambda = [] (int a, int b) { return a + b; };
assert(lambda(1, 2) == 3);

啊哈!这里自动隐藏了 int(*p)(int, int)? - Littlebitter
@Littlebitter,lambda表达式的类型是实现定义的,因此您需要使用auto。您可以将一些lambda表达式(那些不捕获任何内容的)转换为函数指针,但这不是它们的实际类型(类似于您可以将int转换为long,但int不是long)。 - user142019
如果 lambda 为 [] (int a, int b) -> int { return a + b; };,那么是否可以创建指向函数变量的指针,并具有我所描述的类型,而无需使用 auto? - Littlebitter
我相信所有的lambda表达式都可以储存于std::function中,不是吗?还有@Littlebitter,将其分配给你在第一条评论中提到的类型是可行的,因为它没有捕获任何东西。 - chris
是的,你可以这样做 int (*lambda)(int, int) = [] (int a, int b) { return a + b; },因为该 lambda 表达式没有捕获任何变量。 - user142019

1

您甚至不需要一个变量来保存您的lambda表达式 -- 您可以直接调用它:

std::cout << [](int n) { return n + 1 ; } (99) << std::endl ;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接