Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在C+中使用lambda默认值捕获或引用捕获的缺点+;11?_C++_Lambda - Fatal编程技术网

C++ 在C+中使用lambda默认值捕获或引用捕获的缺点+;11?

C++ 在C+中使用lambda默认值捕获或引用捕获的缺点+;11?,c++,lambda,C++,Lambda,在C++11中使用lambda默认值捕获([=])或引用捕获([&])有哪些陷阱 我知道一些陷阱,比如: 如果从lambda创建的闭包的生存期超过了局部变量的生存期,那么闭包中的引用将挂起 默认值捕获是否有任何缺点 与以下各项相比,它具有完全相同的优点和缺点: int value(const T x) { ... } int value(T& x) { ... } 按值捕获涉及复制关闭的值,因此可能意味着该副本需要更多内存消耗和更多处理。使用[=]或[]按值捕获具有创建与捕获的实体

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

我知道一些陷阱,比如:

  • 如果从lambda创建的闭包的生存期超过了局部变量的生存期,那么闭包中的引用将挂起

默认值捕获是否有任何缺点

与以下各项相比,它具有完全相同的优点和缺点:

int value(const T x) { ... }
int value(T& x) { ... }

按值捕获涉及复制关闭的值,因此可能意味着该副本需要更多内存消耗和更多处理。

使用
[=]
[]
按值捕获具有创建与捕获的实体类型完全相同的lambda成员的效果,包括常数,例如。,通过值捕获
常量int
时,即使lambda call运算符是可变的,也不能对结果成员进行变异

const int i = 1;
[=] () mutable { ++i; }(); // Error: increment of read-only variable.
这可以通过使用C++14初始化捕获表达式来解决:

[i = i] () mutable { ++i; }(); // Ok

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

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

首先,这意味着您再次面临悬空指针问题;其次,您可能会意外地修改lambda范围之外的变量,即使看起来您只是在修改本地副本

例如,这将打印
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; 
}
structfoo{
int bar=0;
int bas(){
汽车公司=[=](){
bar++;//这相当于->bar++
返回杆;
};
返回公司();
}
};
int main(){
富富,;

std::回答得很好,我只想补充一点,lambda是对象。因此,在按值捕获时,重复使用lambda对象将使用它的内部状态。这与使用函数如
int-value(const T x){…}完全不同
。有关参考信息,请参见-@Jendas:我不确定您的参考是否正确,但您的回答是正确的,即值是在lambda创建时捕获的,而不是在调用时捕获的。嗨,比尔,谢谢您的回答,默认情况下,值类型被捕获为const,而参考类型为non-constYes。这并不能准确地解决问题,但这是最重要的t我找到了关于lambdas内部状态的信息。嗨,Mike,谢谢你的回答,根据我的理解,捕获值类型成为闭包类的数据成员,引用不会成为闭包类的数据成员。请确认。@Ajayyadav:嗯,它也会成为数据成员,但属于引用类型