C++ 通过值捕获共享\u ptr的lambda如何影响其使用\u count()?
我很好奇当被lambda中的值捕获时,共享_ptr的寿命 我原以为只要lambda仍在内存中,它的C++ 通过值捕获共享\u ptr的lambda如何影响其使用\u count()?,c++,c++11,lambda,shared-ptr,C++,C++11,Lambda,Shared Ptr,我很好奇当被lambda中的值捕获时,共享_ptr的寿命 我原以为只要lambda仍在内存中,它的use\u count()总是>=1,但我的测试显示了一些意想不到的情况:use count下降到0,然后lambda主体内的值递增到1 以下是我测试的内容: 创建一个共享的ptr 定义一个lambda,该lambda通过值捕获共享的\u ptr 重置共享\u ptr 运行lambda 在第3阶段,共享的\u ptr的use\u count()降为0-但对象没有被销毁。在第4阶段-lambda内部-
use\u count()
总是>=1,但我的测试显示了一些意想不到的情况:use count下降到0,然后lambda主体内的值递增到1
以下是我测试的内容:
use\u count()
降为0-但对象没有被销毁。在第4阶段-lambda内部-use\u count()
返回到1。运行lambda后,use\u count()
返回到0,但直到lambda被销毁,对象才被销毁
我想知道这是怎么回事/为什么
use_count()
不应该在lambda定义后为2,然后在lambda中为1吗
#包括
#包括
福班{
公众:
Foo(intv=0):val(v){}
~Foo(){
标准::cout
在lambda定义之后,不应该使用\u count()
为2
它是:
然后在lambda里面放一个
它是:
您感到困惑的部分与lambdas无关。您可以通过创建共享指针的简单副本来产生相同的效果:
std::shared_ptr<Foo> ptr = std::make_shared<Foo>( 0 );
logPtr( ptr );
std::cout << "--- define lambda ---\n";
auto cpy = ptr;
logPtr(ptr);
std::cout << "--- reset ptr ---\n";
ptr.reset();
logPtr(ptr);
// run "lambda"
{
std::cout << "--- run lambda ---\n";
if (cpy) {
cpy->val++;
}
logPtr( cpy );
std::cout << "--- end lambda ---\n";
}
logPtr( ptr );
与lambda无关。以下是不使用lambda的相同代码:。清除共享\u ptr对象后,将无法再获取该对象的使用计数…因为没有对象(也没有共享\u计数器)被指向更多。谢谢!这很有道理。我不知道为什么我认为调用reset()后可以保留对原始指针的访问权限/use_count().事后看来相当愚蠢。我不明白为什么在lambda定义之后use\u count应该增加,因为我的理解是lambda只是常规函数的语法糖,所以为什么use\u count在定义之后增加它应该只在函数/lambda调用之后。@Kapil“因为我的理解是lambda只是常规函数的语法糖”——当涉及到捕获时,lambda更像是一个函子(定义了操作符()
的结构/类)而不是普通函数。在本例中,捕获的值是编译器为实现lambda而生成的函子的隐式成员。因此,创建lambda时,use\u count
将增加,并将shared\u ptr
的副本复制到自身中是有意义的。@Remy感谢您的解释,我现在已经得到了它y use_计数在lamda定义后递增
--- define lambda ---
ptr: refs = 2, val = 0
--- run lambda ---
ptr: refs = 1, val = 1
std::shared_ptr<Foo> ptr = std::make_shared<Foo>( 0 );
logPtr( ptr );
std::cout << "--- define lambda ---\n";
auto cpy = ptr;
logPtr(ptr);
std::cout << "--- reset ptr ---\n";
ptr.reset();
logPtr(ptr);
// run "lambda"
{
std::cout << "--- run lambda ---\n";
if (cpy) {
cpy->val++;
}
logPtr( cpy );
std::cout << "--- end lambda ---\n";
}
logPtr( ptr );
Foo *ptr = new Foo(0);
Foo *cpy = ptr; // create a copy
ptr = null; // "reset" the first pointer
logPtr(cpy); // examine the copy
delete cpy; // release the object through the last active pointer