我有一个相当简单的Event
设计,它定义了一个trigger()
函数并operator co_await()
保留了一组可等待项,当触发时它会恢复这些可等待项。演示在这里。
struct Event{
void trigger();
auto operator co_await();
private:
class Awaitable;
std::set<Awaitable*> awaitables;
bool triggered;
};
struct Event::Awaitable {
explicit Awaitable(Event* e) : evt(e) {}
bool await_ready() const noexcept { return evt->triggered; }
void await_suspend(std::coroutine_handle<> h) {
std::cout << "await_suspend\n";
awaiter = h;
evt->awaitables.insert(this);
}
void await_resume() {std::cout << "await_resume\n"; }
bool await_must_resume() const noexcept { return false; }
private:
friend Event;
Event* evt;
std::coroutine_handle<> awaiter;
public:
};
auto Event::operator co_await() { return Awaitable{this}; }
void Event::trigger() {
triggered = true;
std::cout << "resuming " << awaitables.size() << " awaitable(s)\n";
for(auto&& a : std::move(awaitables))
a->awaiter.resume();
}
在 gcc 中编译并运行显示await_suspend
被调用,这正是我所期望的。但是 MSVCawait_resume
却调用了,我无法解释。这是编译器中的错误还是设计中的 UB?
使用初始化变量是 UB。
修复它
bool triggered = false;
或者bool triggered{};
修复你的问题。godbolt 演示