gpt4 book ai didi

lambda - 理解 C++0x lambda 捕获

转载 作者:行者123 更新时间:2023-12-04 01:03:13 26 4
gpt4 key购买 nike

在最近的 C++0x 草案之一 (n3225.pdf) 中,我们可以找到 5.1.2/10:

The identifiers in a capture-list are looked up using the usual rules for unqualified name lookup (3.4.1); each such lookup shall find a variable with automatic storage duration declared in the reaching scope of the local lambda expression. An entity (i.e. a variable or this) is said to be explicitly captured if it appears in the lambda-expression’s capture-list.



这对我来说似乎有很大的限制。例如,在我看来,以下事情是不允许的:
int global;

struct s {
int x;
void memfun() {
[x,global]{};
}
};

x不一定是自动存储的变量, global 也不是。 .请注意,此捕获子句的目的是让 lambda 对象存储 x 的副本。和 global如果在稍后阶段更改它们,这可能是可取的。我已经知道一个替代方案:
int global;

struct s {
int x;
void memfun() {
int copyx = x;
int copyglobal = global;
[copyx,copyglobal]{};
}
};

但这归结为额外的副本和额外的样板,只是为了捕获 xglobal作为副本。

此外,我在最新的草稿中找不到任何关于如果我们在捕获子句中命名本地引用会发生什么的结论:
int main() {
int i = 0;
int &r = i;
assert([r]{return &r;}() != &i);
}

lambda 对象是“复制引用”还是“复制 int”?如果它通过副本捕获引用的对象,这可以为我们节省之前解决方法中的额外副本。

GCC 显然支持所有这些示例,并在最后一种情况下存储一个 int 的副本(这是可取的,恕我直言)。但我想知道这是否实际上是根据 C++0x 草案的预期行为,或者只是编译器扩展分别是一个实现错误。

编辑:

templatetypedef 指出了 5.1.2/14,它解释了在捕获子句中命名引用时会发生什么。据我所知,这允许我们对第一个示例使用以下解决方法:
int global;

struct s {
int x;
void memfun() {
auto& cx = x;
auto& cglob = global;
[cx,cglob]{};
}
};

蒂亚,
出售

最佳答案

从您发布的内容来看,您的第一个示例似乎是非法的,因为捕获的变量都没有自动持续时间。但是,您可以轻松解决此问题。要捕获数据成员,您可以只捕获它,并且不需要捕获全局,因为您可以直接引用它。

编辑 :正如您所指出的,这不会创建您要捕获的值的本地副本。要在复制时捕获这些变量,您可以捕获它,然后在 lambda 内部显式创建数据成员的本地副本。

至于关于捕获引用的第二个问题,§5.1.2/14 说通过复制捕获引用类型的变量将创建引用值的副本,而不是创建引用的副本。因此,lambda 将拥有它自己的引用在创建时引用的值的副本。

关于lambda - 理解 C++0x lambda 捕获,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5470174/

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