在C++中将参数传递给lambda

Passing parameters to lambda in C++

本文关键字:lambda 参数传递 C++      更新时间:2023-10-16

我似乎错过了C++中lambda机制中的某一点。这是代码:

std::vector<int> vec (5);
int init = 0;
std::generate(begin(vec), end(vec), [init]() mutable { return ++init; });
for (auto item : vec) {
    std::cout << item << " ";
}
std::cout << std::endl << init << std::endl;

如果没有mutable,它就不会编译,因为我正在更改lambda中的init
现在,正如我所理解的,lambda是用init新的新副本为每个向量的项调用的,该副本为0。因此,每次都必须返回1。但是这段代码的输出是:
1 2 3 4 5
0

看起来generate通过复制init在其开始时仅捕获一次;处决但为什么呢?它应该这样工作吗?

现在,正如我所理解的,lambda是用init的一个新的新副本0为每个向量的项调用的。

这是不对的。lambda只是创建类并为其提供operator()的另一种方式。lambda的[]部分描述成员变量,以及它们是通过引用还是值捕获的。lambda的()部分是operator()的参数列表,{}部分是该函数的主体。mutable部分告诉编译器使operator()不是const,因为默认情况下它是const

所以

[init]() mutable { return ++init; }

成为

struct compiler_generated_name
{
    int init; // we captured by value
    auto operator()() // since we used mutable this is non const
    {
        return ++init;
    }
};

为了简洁起见,我在这里使用了一个结构,但lambda被指定为类类型,因此可以使用class

这意味着init与上次迭代中的init相同,因为您只捕获过一次。作为,记住这一点很重要

auto generate_lambda()
{
    int foo = 0;
    return [&foo](){ return ++foo; };
}

当函数返回并且使用它是未定义的行为时,将留下对foo的悬空引用。

lambda是编译器生成的结构,等价于:
struct lambda
{
    int init = 0; // captured value
    auto operator()() // non-const, due to `mutable`
    {
        return ++init;
    }
};

因此,init只被捕获并复制到lambda内部一次——多次调用lambda将不会再次捕获init

您正在处理并看到init的初始值——根据您的预期,您可能想做的是通过引用捕获init。。。。。

std::vector<int> vec (5);
int init = 0;
std::generate(begin(vec), end(vec), [&init]() mutable { return ++init; });
for (auto item : vec) {
    std::cout << item << " ";
}
std::cout << std::endl << init << std::endl;

您的错误在这里"现在,据我所知,lambda被称为,用于每个向量的项,init的新副本为0"(我的斜体)。不正如您所看到的,lambda是完全独立的,因此对矢量代码一无所知。item的初始化在每次评估lambda形式本身时发生(与每次调用结果值相反);这里,这意味着每次调用函数generate时:只调用一次。

int x = ([](int j)->int {return j; }, 3);