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 = shared_from_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.
0 comments