c++ for-loop language-lawyer c++17

¿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.