Почему в С++ 17 изменилась спецификация цикла, основанная на диапазоне "для"?
Я просматривал некрасивый код (который изменял основную последовательность во время итерации), и чтобы изучить определение цикла for
, основанного на диапазоне, я перешел к cppreference.
Там я заметил что-то странное:
Цикл, основанный на диапазоне for
, изменен в С++ 17, но я не вижу причины этого изменения, и код выглядит для меня так же (просто "рефакторинг").
Итак, старый был:
{
auto && __range = range_expression;
for (auto __begin = begin_expr, __end = end_expr; __begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}
Новый -
{
auto && __range = range_expression;
auto __begin = begin_expr;
auto __end = end_expr;
for ( ; __begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}
Почему было сделано это изменение, и заставляет ли оно какие-либо законные программы на С++ 14 демонстрировать неопределенное поведение (UB) на С++ 17?
Ответы
Ответ 1
Использование
auto __begin = begin_expr, __end = end_expr;
требует, чтобы begin_expr
и end_expr
возвращали один и тот же тип. Это означает, что вы не можете иметь тип итератора, который отличается от начального типа. Использование
auto __begin = begin_expr ;
auto __end = end_expr ;
исправляет эту проблему, обеспечивая полную обратную совместимость с С++ 14.
Ответ 2
Это объясняется позже в "заметках":
Начиная с С++ 17, типы begin_expr и end_expr не обязательно должны быть одинаковыми...
и вы не можете иметь это с:
auto __begin = begin_expr, __end = end_expr;