gpt4 book ai didi

使用 C++ 14 中的初始化捕获生成 C++ Lambda 代码

转载 作者:行者123 更新时间:2023-12-01 19:55:02 25 4
gpt4 key购买 nike

我试图理解/澄清当捕获传递给 lambda 时生成的代码,尤其是在 C++14 中添加的广义 init 捕获中。

给出下面列出的以下代码示例,这是我目前对编译器将生成的内容的理解。

情况1:按值捕获/默认按值捕获

int x = 6;
auto lambda = [x]() { std::cout << x << std::endl; };

相当于:

class __some_compiler_generated_name {
public:
__some_compiler_generated_name(int x) : __x{x}{}
void operator()() const { std::cout << __x << std::endl;}
private:
int __x;
};

因此有多个拷贝,一份复制到构造函数参数中,一份复制到成员中,这对于 vector 等类型来说会很昂贵。

情况 2:通过引用捕获/默认通过引用捕获

int x = 6;
auto lambda = [&x]() { std::cout << x << std::endl; };

相当于:

class __some_compiler_generated_name {
public:
__some_compiler_generated_name(int& x) : x_{x}{}
void operator()() const { std::cout << x << std::endl;}
private:
int& x_;
};

参数是引用,成员也是引用,因此没有拷贝。非常适合 vector 等类型。

案例3:

通用初始化捕获

auto lambda = [x = 33]() { std::cout << x << std::endl; };

我的理解是,这在某种意义上与案例1类似它被复制到成员中。

我的猜测是编译器生成的代码类似于...

class __some_compiler_generated_name {
public:
__some_compiler_generated_name() : __x{33}{}
void operator()() const { std::cout << __x << std::endl;}
private:
int __x;
};

此外,如果我有以下内容:

auto l = [p = std::move(unique_ptr_var)]() {
// do something with unique_ptr_var
};

构造函数会是什么样子?它是否也将其移至成员中?

最佳答案

情况 1 [x](){}:生成的构造函数将通过可能的 const 限定引用接受其参数,以避免不必要的情况拷贝:

__some_compiler_generated_name(const int& x) : x_{x}{}
<小时/>

情况 2 [x&](){}:您的假设是正确的,x 通过引用传递和存储。

<小时/>

情况 3 [x = 33](){}:再次正确,x 由值初始化。

<小时/>

情况 4 [p = std::move(unique_ptr_var)]:构造函数如下所示:

    __some_compiler_generated_name(std::unique_ptr<SomeType>&& x) :
x_{std::move(x)}{}

所以是的,unique_ptr_var 被“移入”闭包中。另请参阅《Effective Modern C++》中 Scott Meyer 的第 32 条(“使用 init 捕获将对象 move 到闭包中”)。

关于使用 C++ 14 中的初始化捕获生成 C++ Lambda 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58286397/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com