协程:co_yielded string_views 是否悬空?

Tom*_*ton 3 c++ coroutine dangling-pointer c++23

我想混合 co_yielding 字符串文字和std::strings

Generator<std::string_view> range(int first, const int last) {
    while (first < last) {
        char ch = first++;
        co_yield " | ";
        co_yield std::string{ch, ch, ch};
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,我想知道 std::string 的生命周期?

如果您知道要string_view立即食用,也许是安全的?

for(auto sv : range(65, 91))
   std::cout << sv;
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/d5eoP9aTE

你可以像这样保证安全

Generator<std::string_view> range(int first, const int last) {
    std::string result;
    while (first < last) {
        char ch = first++;
        co_yield " | ";
        result = std::string{ch, ch, ch};
        co_yield result;
    }
}
Run Code Online (Sandbox Code Playgroud)

Nic*_*las 6

co_yield是 的一种奇特形式co_await。这两个都是表达。因此,它们遵循表达规则。作为表达式求值一部分的临时变量将继续存在,直到整个表达式完成。

co_await直到协程恢复后表达式才会完成。这很重要,因为您经常co_await使用纯右值,因此如果您执行像 一样简单的操作co_await some_function(),则需要 的返回值some_function继续存在,因为它的await_resume函数需要能够被调用。

如前所述,co_yield只是 的一种奇特形式co_await。所以规则仍然适用。因此,生成器返回的任何对象都将指向恢复协程的调用之间的string_view有效值。

  • *将指向有效值**在调用恢复**协程之间* - 这非常重要。这意味着,例如,如果将生成的 string_view 存储到一个向量中,那么它们将得到的只是一个“UB 向量”:D (2认同)