You may want to capture your this
pointer into a C++ lambda,
but that captures the raw pointer.
If you need to extend the object's lifetime,
you will need to capture a strong reference.
For plain C++ code, this would be a
std::shared_
ptr
.
For COM objects, this is usually some sort
of smart pointer class like
ATL::
CComPtr
,
Microsoft::
WRL::
ComPtr
,
or
winrt::
com_ptr
.
// std::shared_ptr auto callback = [self = std::shared_from_this(this)]() { self->DoSomething(self->m_value); self->DoSomethingElse(); }; // WRL::ComPtr auto callback = [self = Microsoft::WRL::ComPtr<ThisClass>(this)]() { self->DoSomething(self->m_value); self->DoSomethingElse(); }; // ATL::CComPtr auto callback = [self = ATL::CComPtr<ThisClass>(this)]() { self->DoSomething(self->m_value); self->DoSomethingElse(); }; // winrt::com_ptr template<typename T> auto to_com_ptr(T* p) noexcept { winrt::com_ptr<T> ptr; ptr.copy_from(p); return ptr; } auto callback = [self = to_com_ptr(this)] { self->DoSomething(self->m_value); self->DoSomethingElse(); };
A common pattern for the "capture a strong reference to yourself"
is to capture both a strong reference and a raw this
.
The strong reference keeps the this
alive,
and you use the this
for convenient access to members.
// std::shared_ptr auto callback = [lifetime = std::shared_from_this(this), this]() { DoSomething(m_value); // was self->DoSomething(self->m_value); DoSomethingElse(); // was self->DoSomethingElse(); }; // WRL::ComPtr auto callback = [lifetime = Microsoft::WRL::ComPtr<ThisClass>(this), this]() { DoSomething(m_value); // was self->DoSomething(self->m_value); DoSomethingElse(); // was self->DoSomethingElse(); }; // ATL::CComPtr auto callback = [lifetime = ATL::CComPtr<ThisClass>(this), this]() { DoSomething(m_value); // was self->DoSomething(self->m_value); DoSomethingElse(); // was self->DoSomethingElse(); }; // winrt::com_ptr auto callback = [lifetime = to_com_ptr(this), this]() { DoSomething(m_value); // was self->DoSomething(self->m_value); DoSomethingElse(); // was self->DoSomethingElse(); };
I like to give the captured strong reference a name like
lifetime
to emphasize that its purpose is to
extend the lifetime of the this
pointer.
Otherwise, somebody might be tempted to "optimize" out
the seemingly-unused variable.