Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.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++;Lambdas、捕获、智能ptr和堆栈:为什么这样做?_C++_Variables_Memory Management_Lambda_C++11 - Fatal编程技术网

C++ C++;Lambdas、捕获、智能ptr和堆栈:为什么这样做?

C++ C++;Lambdas、捕获、智能ptr和堆栈:为什么这样做?,c++,variables,memory-management,lambda,c++11,C++,Variables,Memory Management,Lambda,C++11,我一直在玩弄C++11中的一些新特性,我试图编写以下程序,希望它不起作用。让我大吃一惊的是,它确实如此(在Linux x86上的GCC4.6.1上,带有'std=c++0x'标志): #包括 #包括 #包括 std::函数计数在2s中递增(const int from){ std::共享的自参考的自参考(新的自输入); return[from_ref](){return*from_ref+=2;}; } int main(){ 自动iter_1=在_2s中计数(5); 自动iter 2=在2秒内

我一直在玩弄C++11中的一些新特性,我试图编写以下程序,希望它不起作用。让我大吃一惊的是,它确实如此(在Linux x86上的GCC4.6.1上,带有'std=c++0x'标志):

#包括
#包括
#包括
std::函数计数在2s中递增(const int from){
std::共享的自参考的自参考(新的自输入);
return[from_ref](){return*from_ref+=2;};
}
int main(){
自动iter_1=在_2s中计数(5);
自动iter 2=在2秒内计数(10);

对于(size_t i=1;ilambda通过值从\u ref
捕获
,因此它制作了一个副本。由于此副本,当来自\u ref
被销毁时,ref计数不是0,因为lambda中仍然存在副本,所以它是1。

以下内容:

std::shared_ptr<int> from_ref(new int(from));
return [from_ref]() { return *from_ref += 2; };
std::共享的ptr from_ref(新的int(from));
return[from_ref](){return*from_ref+=2;};
大致相当于:

std::shared_ptr<int> from_ref(new int(from));
class __uniqueLambdaType1432 {
  std::shared_ptr<int> capture1;
 public:        
  __uniqueLambdaType1432(std::shared_ptr<int> capture1) :
    capture1(capture1) { 
  }
  decltype(*capture1 += 2) operator ()() const {
    return *capture1 += 2;
  }
};
return __uniqueLambdaType1432(from_ref);
std::共享的ptr from_ref(新的int(from));
类uuu uniquelambdatatype1432{
std::共享ptr capture1;
公众:
__uniqueLambdaType1432(std::shared_ptr capture1):
capture1(capture1){
}
decltype(*capture1+=2)运算符()()常量{
返回*capture1+=2;
}
};
返回uuu uniquelambdatatype1432(来自u ref);

其中,
\uuuuuu uniquelambdatatype1432
是一种程序全局唯一类型,不同于任何其他类型,甚至是由词汇相同的lambda表达式生成的其他lambda类型。程序员无法使用它的实际名称,并且除了由原始lambda表达式生成的对象外,无法创建它的其他实例se构造函数实际上是用编译器魔法隐藏的。

from\u ref被值捕获

如果你替换,你的推理是有效的

return [from_ref]() { return *from_ref += 2; };


那么,我对std::function对象本身在整个实例期间存储捕获值的理解是否正确?通过存储此引用,共享的\u ptr引用计数永远不会达到0?啊,我明白了。多么优雅。@Louis不,不是
函数
对象,而是lambda。
std::function
不知道t lambda的捕获。因此,引用的捕获和存储作为特例处理,而不是作为成员存储在std::function实例中,例如。谢谢。@Louis-捕获的变量存储为编译器生成的lambda对象的成员变量。每个lambda表达式都会生成一个自定义类,该类将res捕获为成员(通过引用或通过值,具体取决于捕获模式),并具有与lambda主体等效的
运算符()
。然后实例化此类以创建lambda表达式的结果值。
return [from_ref]() { return *from_ref += 2; };
return [&from_ref]() { return *from_ref += 2; };