重置 boost::shared_ptr 由来自 lambda 的值捕获

Chr*_*son 4 c++ lambda pass-by-value shared-ptr

在 lambda 中,由于通过值捕获的变量是使用const限定符存储的,从 lambda 重置 boost::shared_ptr 的正确方法是什么?

class Test {};
auto testPtr(boost::make_shared<Test>());

// Error: shared_ptr captured with const
auto lambda1([testPtr]()
{
    testPtr.reset();
});    

// Ok: but "testPtr" could be out of scope once the lambda is called
auto lambda2([&testPtr]()
{
    testPtr.reset();
});
Run Code Online (Sandbox Code Playgroud)

我想这也许可行:

auto copyOfTestPtr(testPtr);

auto lambda3([&testPtr, copyOfTestPtr]()
{
    // is it guaranteed that the variable referenced by &testPtr 
    // will exist later on?

    testPtr.reset();
});

// this reference is not necessary anymore so decrement shared_ptr counter
// (the lambda still having a copy so the counter won't be zero)
copyOfTestPtr.reset()
Run Code Online (Sandbox Code Playgroud)

gcc-5.2.0 给出的带有标志 -std=c++14 的错误是:

main.cpp: In lambda function:
main.cpp:15:27: error: no matching function for call to 
'std::shared_ptr<main()::Test>::reset() const'
Run Code Online (Sandbox Code Playgroud)

只是在寻找最佳实践。

Dra*_*rax 5

在 lambdas [...] 中,通过值捕获的变量使用 const 限定符 [...]

这句话中缺少的部分是“默认”。

情况并非总是如此。如果您想在 lambda 中捕获变量,同时仍然能够在 lambda 中修改它们,您可以mutable在参数列表的末尾添加关键字,如下所示:

  class Test {};
  auto testPtr(boost::make_shared<Test>());

  auto lambda1([testPtr]() mutable
               {
                 testPtr.reset();
               });
Run Code Online (Sandbox Code Playgroud)

也就是说,我必须提到这在提供的代码中似乎完全没有必要,因为在 lambda 范围的末尾,您的共享指针无论如何都会被销毁,因为您是通过复制而不是通过引用捕获它的。