通过右值引用传递协程参数

huangapple go评论75阅读模式
英文:

Passing coroutine parameters by Rvalue reference

问题

自C++/WinRT docs

IASyncAction DoWorkAsync(Param const& value) {
    auto safe_value = value;
    // 在这里访问 safe_value 和 value 都没问题。
    co_await DoOtherWorkAsync();
    // 只能在这里访问 safe_value(不能访问 value)。
}

这是有道理的,只是一个悬空引用。 然而,以前我发现我不得不。
>!

IASyncAction DoWorkAsync(Param value) {
>!    auto safe_value = value;
>!    // 在这里访问 value 和 safe_value 都没问题。
>!    co_await DoOtherWorkAsync();
>!    // 只能在这里访问 safe_value(不能访问 value)。
>! }

而且刚刚我花了太多时间进行调试,才发现又是这个问题。

IASyncAction DoWorkAsync(Param&& value) {
    co_await DoOtherWorkAsync(); // 调用 value 的析构函数
    some_function(std::move(value)); // BOOM
}

这应该发生吗?文档中没有提到。发生了什么?

英文:

From the C++/WinRT docs

IASyncAction DoWorkAsync(Param const& value) {
    auto safe_value = value;
    // It's ok to access both safe_value and value here.
    co_await DoOtherWorkAsync();
    // It's ok to access only safe_value here (not value).
}

This make sense, just a dangling reference. <strike>However, in the past I've found I've had to.</strike>
>! <pre><code>IASyncAction DoWorkAsync(Param value) {
>! auto safe_value = value;
>! // It's ok to access both value here.
>! co_await DoOtherWorkAsync();
>! // It's ok to access only safe_value here (not value).
>! }</pre></code>

and just now I've spent too much time debugging to find out it was this problem yet again.

IASyncAction DoWorkAsync(Param&amp;&amp; value) {
    co_await DoOtherWorkAsync(); // value deconstructor called
    some_function(std::move(value)); // BOOM
}

Is this suppose to happen? The docs don't mention it. What's going on?

答案1

得分: 1

Rvalue references are references; they don't have any special power governing lifetimes outside of the fact that they can manifest temporaries from prvalues like a const&.

As for value parameters, that depends entirely on what the object is doing. Coroutines already store a copy of the parameter internally. You copying it again at the start of the coroutine is meaningful only to the extent that this copy preserves some resource that the original copy would not. That depends on the type of the parameter.

英文:

Rvalue references are references; they don't have any special power governing lifetimes outside of the fact that they can manifest temporaries from prvalues like a const&amp;.

As for value parameters, that depends entirely on what the object is doing. Coroutines already store a copy of the parameter internally. You copying it again at the start of the coroutine is meaningful only to the extent that this copy preserves some resource that the original copy would not. That depends on the type of the parameter.

答案2

得分: 0

I guess the second example never happened, its just the first example. You see cppwinrt generates code like this

void winrt::MyApplication::implementation::UserControl::ToggleButton_Unchecked(winrt::Windows::Foundation::IInspectable const&amp; sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const&amp; e)

and I don't bother making it fit onto one line.

And I guess I thought the parameters where by value when they where by reference, woops.

Corountines are just asking for dangling references!

英文:

I guess the second example never happened, its just the first example. You see cppwinrt generates code like this

void winrt::MyApplication::implementation::UserControl::ToggleButton_Unchecked(winrt::Windows::Foundation::IInspectable const&amp; sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const&amp; e)

and I don't bother making it fit onto one line.

And I guess I thought the parameters where by value when they where by reference, woops.

Corountines are just asking for dangling references!

huangapple
  • 本文由 发表于 2023年2月24日 13:26:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/75552903.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定