I want to mix up the co_yielding string literals and 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};
}
}
However, I'm wondering about the lifetime of the std::string?
Maybe it's safe if you know you are going to consume the string_view
immediately?
for(auto sv : range(65, 91))
std::cout << sv;
https://godbolt.org/z/d5eoP9aTE
You could make it safe like this
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;
}
}
CodePudding user response:
co_yield
is a fancy form of co_await
. Both of these are expressions. And therefore, they follow the rules of expressions. Temporaries manifested as part of the evaluation of the expression will continue to exist until the completion of the entire expression.
co_await
expressions do not complete until after the coroutine resumes. This is important, as you often co_await
on prvalues, so if you do something as simple as co_await some_function()
, you need the return value of some_function
to continue to exist, as its await_resume
function needs to be able to be called.
As previously stated, co_yield
is just a fancy form of co_await
. So the rules still apply. So any string_view
objects returned by your generator will point to valid values between calls to resume the coroutine.