Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.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++ 参考捕获与移动捕获,Lambdas_C++_Pointers_Lambda - Fatal编程技术网

C++ 参考捕获与移动捕获,Lambdas

C++ 参考捕获与移动捕获,Lambdas,c++,pointers,lambda,C++,Pointers,Lambda,我对通过引用将变量传递到lambda(1)和将其移动到捕获列表中的lambda(2)之间的区别感到困惑。两者都产生相同的结果,但我不确定使用其中一种/或的含义是什么(因此,什么是最佳实践?) #包括 #包括 #包括 使用std::cout; 使用std::使_唯一; int main(){ 自动p=使_唯一(500); 自动lambda=[&p](){ cout如果您通过引用捕获,那么lambda的捕获的ptr只引用p,因此当您调用lambda()时,对p的更改将反映出来。一种简单的方法是在运行

我对通过引用将变量传递到lambda(1)和将其移动到捕获列表中的lambda(2)之间的区别感到困惑。两者都产生相同的结果,但我不确定使用其中一种/或的含义是什么(因此,什么是最佳实践?)

#包括
#包括
#包括
使用std::cout;
使用std::使_唯一;
int main(){
自动p=使_唯一(500);
自动lambda=[&p](){

cout如果您通过引用捕获,那么lambda的捕获的
ptr
只引用p,因此当您调用
lambda()
时,对p的更改将反映出来。一种简单的方法是在运行lambda之前重新分配p

p.reset(new int(100));
lambda();
通过引用捕获时,lambda现在将打印100。通过移动捕获,lambda仍然打印500,因为它保留着原始的unique_ptr,直到
lambda
超出范围后才会删除


相反,使用移动捕获时,您已将指针移出
p
,因此在为
p
指定新值之前取消引用
p
是无效的。如果在创建lambda后尝试取消引用p,您可能会看到运行时错误。

显然,它们是不同的

为了实际理解差异和含义,我们可以用
struct
进行类比


参考Lambda 以下是lambda:

 auto lambda = [&p]() {
   cout << "Inside the lambda -- value = " << *p << '\n';
 };
 auto lambda = [ptr = std::move(p)]() {
   cout << "Inside the lambda -- value = " << *ptr << '\n';
 };
因此,在构造lambda时,对
std::unique_ptr
引用将存储在lambda本身中。这可能会导致很大的影响:引用的对象(
p
)不属于lambda

例如,在这种情况下,您必须关心lambda之外的
p
的活跃度,以避免出现诸如悬挂引用之类的问题

例如:

int main() {    
  auto p = make_unique<int>(500);     
  auto lambda = [&p]() {
    cout << "Inside the lambda -- value = " << *p << '\n';
  };

  p.reset();  //  p has been reset here!!! The pointer is NULL!

  lambda();  // Undefined Behaviour here. Because lambda will call *p inside which is null!
}
正如您所看到的,场景现在完全不同了,“内部”变量(
ptr
)不再是参考

在这种情况下,lambda将在其构造期间获得指针的所有权。遵循
std::move
背后的逻辑就像lambda“窃取”资源一样

因此,在lambda构造之后,
p
(主
main
的局部变量)和
ptr
(lambda的内部变量)之间不再存在相关性。它们是两个不同的独立对象

实际上:

int main() {    
  auto p = make_unique<int>(500);     
  auto lambda = [ptr = std::move(p)]() {
    cout << "Inside the lambda -- value = " << *ptr << '\n';
  };

  // now p (the local variable of main) is null because lambda stole it!

  assert(p == nullptr); // !!!!   

  // here you can even reassign p. The object inside lambda is another object.

  lambda();  
}
int main(){
自动p=使_唯一(500);
自动lambda=[ptr=std::move(p)](){

所示的示例都不能将任何变量传递到lamba中。lamba函数没有参数。它们所显示的是lambda通过值或引用捕获变量。这与将某个变量作为参数传递给lambda有根本性的区别,您应该首先关注理解其区别。Thanks,这是一个重要的区别。传球会发生在括号内。
int main() {    
  auto p = make_unique<int>(500);     
  auto lambda = [&p]() {
    cout << "Inside the lambda -- value = " << *p << '\n';
  };

  p.reset();  //  p has been reset here!!! The pointer is NULL!

  lambda();  // Undefined Behaviour here. Because lambda will call *p inside which is null!
}
 auto lambda = [ptr = std::move(p)]() {
   cout << "Inside the lambda -- value = " << *ptr << '\n';
 };
struct __lambda_move {
  __lambda_reference(std::unique_ptr<int> p): ptr(p) {}

  void operator()() const {
    std::cout << "Inside the lambda -- value = " << *(this->ptr) << '\n';
  }

 private:
   std::unique_ptr<int> ptr;
};

auto lambda = __lambda_move(std::move(p));
int main() {    
  auto p = make_unique<int>(500);     
  auto lambda = [ptr = std::move(p)]() {
    cout << "Inside the lambda -- value = " << *ptr << '\n';
  };

  // now p (the local variable of main) is null because lambda stole it!

  assert(p == nullptr); // !!!!   

  // here you can even reassign p. The object inside lambda is another object.

  lambda();  
}