gpt4 book ai didi

c++ - 什么时候在 C++11 lambda 的定义中需要明确命名的变量捕获?

转载 作者:行者123 更新时间:2023-11-30 01:02:19 26 4
gpt4 key购买 nike

到目前为止,在查看 C++ lambda expressions in the c++11 style 时,我将它们全部分为两大类:捕获和非捕获。

非捕获 lambda,虽然在编写方式上受到更多限制,但在使用方式上更加灵活——它们可以是 implicitly converted to analogous function-pointer types ;他们不鼓励无偿std::function<…>用法,它们的实现范围是less likely to creep out and cause side-effect problems , 等等。

然而,捕获 lambda 可以用更广泛的方式编写。不可否认,它们并没有赋予我刚才提到的所有这些好处。但是捕获 lambda 弥补了它可以解决的大量问题,它打破了堆栈的前馈函数调用 DAG 的限制,提供了对周围范围的多种访问形式。

不过,这就是我的理解。当我使用捕获 lambda 表达式时,当我需要一到两个变量时,我倾向于显式引用捕获特定变量:

using lambda_t = std::function<std::add_pointer_t<void>(int)>;

lambda_t lambda_explicit = [&one, &another](int descriptor) {
return ::mmap(nullptr, one, PROT_READ, MAP_PRIVATE, descriptor, another);
};

…如果有两个以上,我更愿意(出于同等的语法强制症和懒惰)避免显式命名捕获,而支持对所有内容的引用形式:

lambda_t lambda_everything = [&](int descriptor) {
return ::mmap(nullptr, one, PROT_READ, MAP_PRIVATE, descriptor, another);
};

... 注意,更改 lambda 捕获的形式不会改变任何关于 lambda 类型的明显信息——例如,调用签名是相同的。这是违反直觉的,因为看起来 much of the way capturing works is vaguely specified and somewhat implementation-specific , 有点与捕获表达式提供的详细正式多样性成反比(或者它是声明?还是声明列表?……我不确定)如果你去最后一个链接,你会看到它的全部荣耀然后向下滚动一点。

我什至没有触及绝大多数可能性——我几乎总是只做其中之一:

  1. 完全没有捕获;
  2. 一个或两个明确命名的变量,通过引用捕获;或
  3. 不分青红皂白地按引用捕获所有内容:[&]

在什么情况下我应该特意使用一种捕获方式而不是另一种捕获方式?

哪些形式是特例,一般应避免?哪些有明显的惩罚——在性能、代码大小、潜在的 UB 或其他方面?任何捕获表单是否具有切实和/或简单的好处?

最佳答案

What are the circumstances in which I should go out of the way to use one form of capturing over the other?

当您仅限于使用无状态函数时,捕获不是一种选择,并且您仅限于 1。将回调注册到 C 语言 API 时通常是这种情况。

当你想将一个对象移动到一个捕获中时,你必须将它移动到一个命名的捕获中,因此被限制为 2。但这在 C++11 中是不可能的;您需要从 C++14 捕获的广义 lambda。广义捕获对于具有不需要与外部通信的初始状态的可变 lambda 也很有用(除非明确返回)。

此外,当您希望通过值捕获一组变量并通过引用捕获另一组变量时,默认情况下您最多可以捕获一组,并且必须至少显式捕获一组。也就是说,这可能是一个特例。我不记得曾经需要这个。

我认为没有必要使用默认捕获,但它可以节省大量冗余输入。

关于c++ - 什么时候在 C++11 lambda 的定义中需要明确命名的变量捕获?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56238211/

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