¿Por qué cambió la especificación de bucle ''for'' basada en rango en C++ 17?
for-loop language-lawyer (2)
Se explica más adelante en las "notas":
A partir de C ++ 17, los tipos de begin_expr y end_expr no tienen que ser los mismos ...
y no puedes tener eso con:
auto __begin = begin_expr, __end = end_expr;
Esta pregunta ya tiene una respuesta aquí:
Estaba mirando algún código feo (que modificaba la secuencia subyacente mientras iteraba), y para explorar la definición del bucle basado
for
rango, fui a
cppreference
.
Allí noté algo extraño:
El rango basado
for
bucle cambió en C ++ 17, pero no veo la razón del cambio, y el código me parece igual (solo "refactorizado").
Entonces el viejo era:
{
auto && __range = range_expression;
for (auto __begin = begin_expr, __end = end_expr; __begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}
El nuevo es
{
auto && __range = range_expression;
auto __begin = begin_expr;
auto __end = end_expr;
for ( ; __begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}
¿Por qué se realizó este cambio y hace que algún programa legal de C ++ 14 exhiba un comportamiento indefinido ( UB ) en C ++ 17?
Utilizando
auto __begin = begin_expr, __end = end_expr;
requiere que
begin_expr
y
end_expr
devuelvan el mismo tipo.
Esto significa que no puede tener un tipo de iterador centinela que sea diferente del tipo inicial.
Utilizando
auto __begin = begin_expr ;
auto __end = end_expr ;
soluciona ese problema al tiempo que demuestra la compatibilidad con versiones anteriores de C ++ 14.