在C ++ 11中使用按值或引用使用lambda默认捕获的缺点? [英] Disadvantage of using lambda default capture by value or reference in C++11?

查看:44
本文介绍了在C ++ 11中使用按值或引用使用lambda默认捕获的缺点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C ++ 11中按值([=])或按引用([&])使用lambda默认捕获有哪些陷阱?

What are the pitfalls of using lambda default capture by value ([=]) or by reference ([&]) in C++11?

我知道一些陷阱,例如:

I know some pitfalls like:

  • 如果从lambda创建的闭包的生存期超过了局部变量的生存期,那么闭包中的引用将悬而未决?

按值进行默认捕获是否有任何不利之处?

Does default capturing by value have any disadvantages?

推荐答案

我认为您提到的悬而未决的参考问题是主要的陷阱.

I think the dangling reference problem you mentioned is the main pitfall.

然而,有时会忽略的另一件事是,即使在成员函数中使用按值捕获lambda时,它也不会创建已使用的成员变量的副本,而只会创建一个副本. this指针.

One other thing that is sometimes overlooked however, is that even when one uses a capture-by-value-lambda in a member function, it doesn't create a copy of the used member variables, but only makes a copy of the this pointer.

首先,这意味着您再次打开了悬空指针问题,其次,您可能不小心修改了lambda范围之外的变量,即使看起来像您只是在修改本地副本.

For one, this means that you are again open to the dangling pointer Problem and second, you might accidentally modify variables outside of the scope of the lambda, even when it looks like, you are only modifying a local copy.

例如这将打印0 1 1而不是0 1 0

struct Foo {
    int bar=0;
    int bas() {
        auto inc = [=]() {          
            bar++;  //this is equivalent to this->bar++ 
            return bar; 
        };
        return inc();
    }
};

int main() {
    Foo foo;
    std::cout << foo.bar <<" ";
    std::cout << foo.bas() << " ";
    std::cout << foo.bar << std::endl; 
}


只是为了避免与@Snps提出的观点有关的混淆:
如果barbas()中的局部变量(并因此被值捕获),则上述lambda将不会编译,因为按值捕获的变量默认为const,除非您将lambda明确指定为可变的. 因此,如果您考虑一下,很明显,酒吧不会被复制,但是在读取或编写代码时很容易忘记.


Just to avoid confusion related to the point made by @Snps:
If bar was a local variable in bas() (and thus be captured by value), the above lambda would not compile, as by-value-captured-variables are by default const, unless you explicitly specify the lambda as mutable. So if you think about it, it is clear that bar is not copied, but that's easily forgotten, when reading or writing code.

这篇关于在C ++ 11中使用按值或引用使用lambda默认捕获的缺点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆