协程:co_yielded string_views晃动吗?

Coroutines: Do co_yielded string_views dangle?

提问人:Tom Huntington 提问时间:12/2/2022 最后编辑:Tom Huntington 更新时间:12/2/2022 访问量:94

问:

我想混淆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};
    }
}

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

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

for(auto sv : range(65, 91))
   std::cout << sv;

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;
    }
}
C++ 协程 悬空指针 C++23

评论

1赞 Ben 12/2/2022
如果它作为本地存储在 coro 框架中,我会说这很好。我猜这不是。但我不知道。std::string

答:

6赞 Nicol Bolas 12/2/2022 #1

co_yield是 的一种花哨形式。这两者都是表达式。因此,他们遵循表达规则。作为表达式评估的一部分表现出来的临时性将继续存在,直到整个表达式完成。co_await

co_await表达式在协程恢复后才会完成。这很重要,因为你经常使用 prvalues,所以如果你做一些简单的事情,你需要 的返回值继续存在,因为它的函数需要能够被调用。co_awaitco_await some_function()some_functionawait_resume

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

评论

2赞 Not a real meerkat 12/2/2022
将指向恢复协程的调用之间的有效值 - 这非常重要。这意味着,例如,如果一个人将生成的string_view存储到一个向量中,那么他们将得到的只是一个“UB向量”:D