C++ 协程的 return_void 和 return_value 的返回类型

ggu*_*lia 5 c++ c++20 c++-coroutine

return_void

考虑下面的协程ReturnObject并注意方法之前的注释ReturnObject::promise_type::return_void

struct ReturnObject {
        struct promise_type {
            int val_{23};
            ReturnObject get_return_object() {
                return {std::coroutine_handle<promise_type>::from_promise(*this)}; 
            }
        std::suspend_never initial_suspend() { return {}; }
        std::suspend_never final_suspend() noexcept { return {}; }
        void unhandled_exception() {}

         /*** NOTE THIS ***/
        //void return_void(){  }
        
        /*** AND THIS ***/
        int return_void(){ return 101; }
      };
      
      std::coroutine_handle<promise_type> h_; 
      ReturnObject(std::coroutine_handle<promise_type> h):h_{h}{ } 
      operator std::coroutine_handle<promise_type>() const { return h_; } 
};

Run Code Online (Sandbox Code Playgroud)

编译器资源管理器上的完整代码

网络上和本文(第 37 页)中的标准用法表明该return_void方法返回void,但在 gcc 11.2 中,return_voidwithint返回类型也可以工作。它是否正确 ?如果是,

  1. 为什么它适用于 void 和非 void 返回类型?
  2. return_void如果返回类型为非 void,则返回值会怎样?

return_value

return_value在 gcc 中也可以观察到与该方法类似的效果。对于return_value返回的数据,有没有办法直接访问返回的数据,类似于普通子例程/函数的返回值?

在编译器资源管理器上检查代码

更新:

在 @useless 的建议之后,我向两者添加了非[[nodiscard]]void返回类型和启用标志。return_voidreturn_value-Wall

令人惊讶的是return_voidreturn_value我什至没有收到 gcc-10.2 的警告。检查这里,但 gcc-11.2 给了我一个警告(这里

我收到的返回类型的编译器警告如下所示return_valueint

warning: ignoring return value of 'int ReturnObject::promise_type::return_value(int)', declared with attribute 'nodiscard' [-Wunused-result]
   31 |     co_return 7;
      |               ^
<source>:18:27: note: declared here
   18 |         [[nodiscard]] int return_value(int val){return val;}
Run Code Online (Sandbox Code Playgroud)

我不相信编译器警告co_returns 值被丢弃。实际上,被丢弃的返回值来自该方法return_value,但编译器设法以某种方式掩盖它

感谢您提前查看该帖子并提出建议。

use*_*522 6

[stmt.return.coroutine]/2表示表达式

promise_object.return_value(...)
Run Code Online (Sandbox Code Playgroud)

promise_object.return_void()
Run Code Online (Sandbox Code Playgroud)

(以所使用的为准co_return)应为 类型void

因此,任一函数的返回类型必须是void(如果它被 a​​ 使用co_return)。

MSVC 确实正确地拒绝了该程序:

<source>(31): error C7625: The type of a coroutine promise return_value or return_void expression must be void
<source>(18): note: see declaration of 'ReturnObject::promise_type::return_value'
Run Code Online (Sandbox Code Playgroud)