0

I want to capture a shared_ptr in my lambda expression. Tried two methods:

  1. Capture the shared pointer

    error: invalid use of non-static data member A::ptr

  2. Create a weak pointer and capture it (Found this via some results online). I'm not sure if I'm doing it the right way

    error: ‘const class std::weak_ptr’ has no member named ‘someFunction’

Before anyone flags it as a duplicate, I am aware it might be similar to a some other questions but none of their solutions seem to work for me. Want to know what I'm doing wrong and how to resolve it, that's why I'm here.

file.h

#include "file2.h"

class A{
   private:
      uint doSomething();
      std::shared_ptr<file2> ptr;
}

file.cpp

#include "file.h"

uint A::doSomething(){
   ...

   // Tried using weak pointer
   //std::weak_ptr<Z> Ptr = std::make_shared<Z>();
   
   auto t1 = [ptr](){
   auto value = ptr->someFunction;}
   
   // auto t1 = [Ptr](){
   // auto value = Ptr.someFunction;}
   
   ...
   }
Friday
  • 23
  • 1
  • 5
  • What about `auto t1 = [p=ptr](){` (and then using `p` instead of `ptr` in the lambda body)? Requires C++14 but should work fine – UnholySheep Apr 27 '22 at 09:08
  • or `auto t1 = [this](){` should work as well. – Yksisarvinen Apr 27 '22 at 09:09
  • @UnholySheep I believe it's fine to still call it `ptr`: `[ptr=ptr]` – user253751 Apr 27 '22 at 09:12
  • @UnholySheep: Still throws the same error: ‘const class std::weak_ptr’ has no member named ‘someFunction’ – Friday Apr 27 '22 at 09:12
  • @Friday then you must have done something different, since you are apparently capturing a `std::weak_ptr` (which is commented out in the code you show) instead of the `std::shared_ptr` member – UnholySheep Apr 27 '22 at 09:14
  • @user253751 you are right, I got confused and thought that shadowing the name wasn't allowed in a lambda capture initializer – UnholySheep Apr 27 '22 at 09:16
  • @UnholySheep: I think I'm capturing the right pointer only. Please correct me if I'm wrong. ptr (std::shared_ptr) Ptr (std::weak_ptr) – Friday Apr 27 '22 at 09:20
  • 1
    `weak_ptr` can't be used with `operator->`, because that would break its core functionality. You don't know if `weak_ptr` still points to a valid object or not. You need to `lock()` your `weak_ptr`, then examine if resulting `shared_ptr` is not `nullptr` and only then you can use the pointed-to object. – Yksisarvinen Apr 27 '22 at 09:25

2 Answers2

6

You cannot capture member directly, either you capture this or capture with an initializer (C++14)

auto t1 = [this](){ auto value = ptr->someFunction();};
auto t1 = [ptr=/*this->*/ptr](){ auto value = ptr->someFunction();};
Jarod42
  • 203,559
  • 14
  • 181
  • 302
1

It's better to use weak_ptr instead. Passing this pointer is a trick to solve the problem. The reasons are mentioned here: https://floating.io/2017/07/lambda-shared_ptr-memory-leak/