Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: Allow delegates consisting of weak reference + lambda #1371

Closed
oldnewthing opened this issue Nov 20, 2023 · 0 comments · Fixed by #1372
Closed

Feature request: Allow delegates consisting of weak reference + lambda #1371

oldnewthing opened this issue Nov 20, 2023 · 0 comments · Fixed by #1372

Comments

@oldnewthing
Copy link
Member

Version

2.0.230706.1

Summary

We have found that a very common pattern for event handlers is to capture a weak reference into a lambda, and in the event handler, try to upgrade the weak reference to a strong one, and if so, do some work:

widget.Closed([weak = get_weak(), data](auto&& sender, auto&& args)
{
    if (auto strongThis = weak.get())
    {
        strongThis->do_all_the_things(data);
    }
});

We propose extending the existing delegate constructors to permit a winrt::weak_ref + lambda (or std::weak_ptr + lambda), which simplifies the above to

widget.Closed({ get_weak(), [this, data](auto&& sender, auto&& args)
{
    do_all_the_things(data);
} });

Reproducible example

No response

Expected behavior

No response

Actual behavior

No response

Additional comments

No response

oldnewthing added a commit to oldnewthing/cppwinrt that referenced this issue Nov 20, 2023
We have found that a very common pattern for event handlers is
to capture a weak reference into a lambda, and in the event handler,
try to upgrade the weak reference to a strong one, and if so, do some work:

```cpp
widget.Closed([weak = get_weak(), data](auto&& sender, auto&& args)
{
    if (auto strongThis = weak.get())
    {
        strongThis->do_all_the_things(data);
    }
});
```

This commit extends the existing delegate constructors to permit a
`winrt::weak_ref` + lambda (or `std::weak_ptr` + lambda), which
simplifies the above to

```cpp
widget.Closed({ get_weak(), [this, data](auto&& sender, auto&& args)
{
    do_all_the_things(data);
} });
```

## Implementation notes

A lambda and pointer to member function are hard to distinguish
in a template parameter list. In theory, we could use SFINAE or
partial specialization, but a simpler solution is to distinguish
the two inside the body of the constructor, via
`std::is_member_function_pointer_v`.

The `com_ptr` and `shared_ptr` variants of the test were
unified, since I found myself editing two nearly identical tests.

Fixes microsoft#1371
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant