29
std::function<int()> void f1()
{
    int a, b, c, d, ..., x, y, z;

    return [=] { return a + b + c; };
}

对比

std::function<int()> void f2()
{
    int a, b, c, d, ..., x, y, z;

    return [a, b, c] { return a + b + c; };
}

不用说,前者比后者更短、更方便、更优雅。

但是,我仍然担心:

从性能的角度来看,后者总是优于前者吗?

标准是否保证 lambda 表达式仅捕获必要的变量?即在前一个示例中,仅捕获了 a、b、c,未捕获到未使用的变量 d、...、x、y、z。

4

3 回答 3

44

该标准保证,如果您执行默认捕获,则该默认捕获将从周围环境中捕获的唯一变量是您在 lambda 中实际使用的变量。

因此,指定要捕获的单个变量可以作为您期望使用的文档,但绝不应该影响性能。

对于任何关心的人,标准中的确切措辞是(§5.1.2/11, 12):

11 如果 lambda 表达式具有关联的 capture-default 及其复合语句 odr-uses (3.2)this或具有自动存储持续时间的变量,并且未显式捕获使用 odr 的实体,则称使用 odr 的实体被隐式捕获;此类实体应在 lambda 表达式的到达范围内声明。[注释省略]

12 如果实体被显式或隐式捕获,则该实体被捕获。[...]

概括

隐式捕获规范 ([=][&]) 只会捕获 lambda 中使用的变量,因此隐式与显式捕获永远不会影响性能。

于 2013-09-26T02:25:49.863 回答
3

不是真的...大多数其他语言也不需要(甚至不允许)您指定要捕获的内容。

让编译器在可能的情况下推断出什么是必要的。
它不会出错,也不会“意外”捕获 lambda 中未使用的内容。
如果您想要明确(有时这是有道理的),这就是传统函子的完美选择。

于 2013-09-26T02:06:31.637 回答
0

从语义上讲,您应该只将那些您实际需要的变量导入到您的 lambda 范围内。对于除内置类型之外的任何内容,您也可能希望通过引用进行捕获。

于 2013-09-26T02:10:12.917 回答