总是在lambda表达式中捕获所有内容是不好的做法?

时间:2013-09-26 01:57:05

标签: c++ performance c++11 coding-style lambda

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

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

VS

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不是。

3 个答案:

答案 0 :(得分:24)

标准保证如果你进行默认捕获,那么从周围环境中捕获的默认捕获的唯一变量就是你在lambda中实际使用的变量。

因此,指定要捕获的各个变量充当您期望使用的文档,但不应影响性能。

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

  

11如果lambda表达式具有关联的capture-default及其复合语句odr-使用(3.2)this或具有自动存储持续时间的变量且未明确捕获使用了odr的实体,则据说这个使用过的实体是隐含的;这些实体应在lambda表达式的范围内声明。 [注意已删除]

     

12如果明确或隐含地捕获实体,则捕获该实体。 [...]

摘要:隐式捕获规范([=][&])将仅捕获lambda中使用的变量。

答案 1 :(得分:2)

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

让编译器在可能的情况下推断出必要的内容 它不会出错,也不会“意外地”捕获lambda中未使用的东西 如果你想要明确(有时候这是有道理的),那就是传统的仿函数最适合的。

答案 2 :(得分:0)

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