gpt4 book ai didi

c++ - 协程参数的生命周期是多少

转载 作者:行者123 更新时间:2023-12-04 17:19:51 26 4
gpt4 key购买 nike

#include <iostream>
#include <experimental/coroutine>
#include <string>
#include <thread>
struct InitialSuspend{
bool await_ready(){
return false;
}
bool await_suspend(std::experimental::coroutine_handle<> h){
return false;
}
void await_resume(){

}
};
struct FinalSuspend{
bool await_ready() noexcept{
return false;
}
void await_suspend(std::experimental::coroutine_handle<> h) noexcept{
std::cout<<"FinalSuspend await_suspend\n";
}
std::string await_resume() noexcept{
std::cout<< "await_resume for FinalSuspend\n";
return "await_resume for FinalSuspend\n";
}
};
struct Task{
struct promise_type;
using coroutine_type = std::experimental::coroutine_handle<promise_type>;
struct promise_type{
auto initial_suspend(){
return InitialSuspend{};
}
void unhandled_exception(){
std::cout<<"unhandled_exception\n";
std::terminate();
}
auto final_suspend() noexcept{
return FinalSuspend{};
}
// void return_value(std::string const& v){
// value_ = v;
// }
void return_void(){

}
auto get_return_object(){
return Task{coroutine_type::from_promise(*this)};
}
std::string value_;
};
coroutine_type handler_;
};
struct AwaitAble{
bool await_ready(){
return false;
}
void await_suspend(std::experimental::coroutine_handle<> h){
std::cout<<"await_suspend\n";
}
std::string await_resume(){
std::cout<<"await_resume\n";
return "abc";
}
};
struct Observe0{
Observe0(int v):id_(v){
std::cout<< id_ <<" constructor0\n";
}
~Observe0(){
std::cout<< id_ <<" destroy0\n";
}
Observe0(Observe0 const& v):id_(v.id_+1){
std::cout<< id_<<" copy constructor0\n";
}
Observe0(Observe0&& v):id_(v.id_+1){
std::cout<< id_<<" move constructor0\n";
}
int id_;
};
Task MyCoroutine(Observe0 p){
auto r1 = co_await AwaitAble{};
}
int main(){
Observe0 aa{1}; //#1
auto r = MyCoroutine(aa); //#2
std::cout<<"caller\n";
r.handler_.resume();
r.handler_.destroy();
std::cin.get();
}
output是:
1  constructor0
2 copy constructor0
3 move constructor0
await_suspend
2 destroy0
caller
await_resume
FinalSuspend await_suspend
3 destroy0
1 destroy0
我们可以通过上面的代码观察一个对象的创建或销毁。第一次打印发生在 #1 , 构造对象 a .第二次打印发生在 #2 处的协程参数初始化时.第三次打印发生在协程参数拷贝的初始化时,由以下规则来规定:
[dcl.fct.def.coroutine#13]

When a coroutine is invoked, after initializing its parameters ([expr.call]), a copy is created for each coroutine parameter. For a parameter of type cv T, the copy is a variable of type cv T with automatic storage duration that is direct-initialized from an xvalue of type T referring to the parameter.


这三个对象都有自己唯一的编号,方便观察关联对象的生命周期。根据第五次打印,析构函数是为 调用的。协程参数 谁的名字是 p .然而,根据 [expr.await#5.1]

Otherwise, control flow returns to the current coroutine caller or resumer ([dcl.fct.def.coroutine]) without exiting any scopes ([stmt.jump]).


意味着暂停协程并将控制权转移给调用者,协程的参数范围不视为退出。因此,参数的生命周期不应结束。为什么参数的析构函数在第一次传递给协程的调用者之后被调用?它应该被视为编译器中的错误吗?

最佳答案

参数的生命周期不是函数作用域的一部分;它是 caller's scope 的一部分:

The initialization and destruction of each parameter occurs within the context of the calling function.


这就是 [dcl.fct.def.coroutine#13] 存在的全部原因。为了让协程保留其参数,它必须拥有它们。这意味着它必须将它们从参数复制/移动到本地自动存储中。

关于c++ - 协程参数的生命周期是多少,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66897608/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com