O C++23 deveria corrigir problemas com for
loops baseados em intervalo. O padrão C++ agora tem uma redação que posso rastrear até p2718r0 , incluindo o seguinte exemplo no final da seção "A instrução for baseada em intervalo [stmt.ranged]
" (observe o undefined behavior
comentário:
using T = std::list<int>;
const T& f1(const T& t) { return t; }
const T& f2(T t) { return t; }
T g();
void foo() {
for (auto e : f1(g())) {} // OK, lifetime of return value of g() extended
for (auto e : f2(g())) {} // undefined behavior
}
Digamos que eu escreva uma corrotina usando o C++23 std::generator
que recebe um argumento por valor, ou seja, seguindo a regra CP.53 das diretrizes básicas do C++: Parâmetros para corrotinas não devem ser passados por referência :
#include <generator>
#include <string>
#include <iostream>
std::generator<std::string> generator_f(std::string x) {
co_yield x;
}
std::string sample_g() { return "abc"; }
int main() {
for(const auto& elem: generator_f(sample_g())) {
std::cout << elem << "\n";
}
return 0;
}
Presumo que, com base no exemplo do padrão C++, o código no for
loop main()
acima seja um comportamento indefinido.
Qual é a lógica por trás da regra de comportamento indefinido ilustrada pelo exemplo no padrão C++? A desvantagem é que ela torna o uso de std::generator
argumentos with em um loop propenso a erros (que é onde você gostaria de usar um gerador, ou seja, não corrige realmente problemas de tempo de vida com instruções for
baseadas em intervalo ).for