调查一个依赖参数的查找问题并解决它 - 《旧新事物》

  • Problem: In winrt::impl::promise_base::set_completed, there is an unqualified call to invoke() that intended to resolve to winrt::impl::invoke but instead resolves to std::invoke due to argument-dependent lookup.
  • Cause: In C++17, coroutines were an experimental feature and the first type in Args1... was std::experimental::coroutine_traits. After promoting coroutines out of the experimental namespace in C++20, std namespace was added to the argument-dependent lookup search, resulting in std::invoke being found.
  • Solution for older version: To fix the issue in an older version of C++/WinRT without upgrading, one can put a better invoke in the searched-in namespaces. For example, declare a version of invoke in the winrt::Windows::Foundation namespace that is considered better than std::invoke (with a non-deduced final status parameter) before including winrt/Windows.Foundation.h. If using WIL, include wil/cppwinrt.h before any C++/WinRT header. Then implement the invoke by forwarding to winrt::impl::invoke and assert that the C++/WinRT version is pre-bug-fix.
  • Author: Raymond Chen has been involved in Windows evolution for over 30 years. His Web site The Old New Thing grew popular and led to a book. He occasionally appears on the Windows Dev Docs Twitter account.
  • Namespace details: Technically, winrt::impl and wil::details namespaces are for internal use and not supposed to be relied on as they can change. But in this case, they are stable within the context of the fix as the static_assert will fire once the header is upgraded, indicating the fix is no longer needed.
阅读 7
0 条评论