Why must the return type of a coroutine be move-constructible?

前端 未结 1 1802
刺人心
刺人心 2021-01-18 06:29

Consider the following code that defines the invoker class - a minimal return type for a coroutine. We explicitly delete the copy and move constructors of the

1条回答
  •  一整个雨季
    2021-01-18 07:09

    With C++17 guaranteed copy elision, the invoker returned by get_return_object() is a prvalue, and hence should not be materialized until after it is returned from f().

    That would only be true if a coroutine function call were guaranteed to generate its return value by a call equivalent to building a bunch of objects in a separate stack, then calling get_return_object() on one of them. That is, the question is whether the path from get_return_object() to the function call itself only uses prvalues.

    Let's look at what the standard says:

    The expression promise.get_­return_­object() is used to initialize the glvalue result or prvalue result object of a call to a coroutine. The call to get_­return_­object is sequenced before the call to initial_­suspend and is invoked at most once.

    Note that it says that it initializes the "prvalue result object". This is the same language used in the definition of the behavior of the return statement:

    the return statement initializes the glvalue result or prvalue result object of the (explicit or implicit) function call by copy-initialization from the operand.

    The only hesitation I would have in saying that the standard clearly requires guaranteed elision between get_return_object and the caller of the coroutine is the last part about initial_suspend. Because something happens between the initialization of the "prvalue result object" and returning control to the caller, it could be that there has to be an intermediary, which must be copied/moved from.

    But the fact that it's using the exact same language as return suggests that it ought to be providing the exact same behavior too.

    When running on MSVC's coroutine implementation, your code (with only minor changes for differences in where certain types are defined) works fine. Coupled with the above evidence, I would say that this suggests that this is a compiler bug.

    0 讨论(0)
提交回复
热议问题