为什么在C ++ 17中基于范围的“ for”循环规范发生了变化?

NoS*_*tAl 60 c++ for-loop language-lawyer c++17

我查看了一些丑陋的代码(在迭代时修改了基础序列),并探索了基于范围的for循环的定义,我去了cppreference

在那里,我注意到了一些奇怪的事情:

基于范围的for循环在C ++ 17中已更改,但我看不到更改的原因,并且代码对我来说看起来相同(只是“重构”)。因此,旧的是:

{
  auto && __range = range_expression;
  for (auto __begin = begin_expr, __end = end_expr; __begin != __end; ++__begin) {
    range_declaration = *__begin;
    loop_statement
  }
} 
Run Code Online (Sandbox Code Playgroud)

新的是

{
  auto && __range = range_expression;
  auto __begin = begin_expr;
  auto __end = end_expr;
  for ( ; __begin != __end; ++__begin) {
    range_declaration = *__begin;
    loop_statement
  }
} 
Run Code Online (Sandbox Code Playgroud)

为什么要进行此更改,并且它会使任何合法的C ++ 14程序在C ++ 17中表现出未定义的行为(UB)?

Nat*_*ica 79

使用

auto __begin = begin_expr, __end = end_expr;
Run Code Online (Sandbox Code Playgroud)

同时需要begin_exprend_expr返回相同的类型。这意味着您的哨兵迭代器类型不能与开始类型不同。使用

auto __begin = begin_expr ;
auto __end = end_expr ;
Run Code Online (Sandbox Code Playgroud)

解决了与C ++ 14完全向后兼容的问题。

  • @LF IIRC范围最初定于C ++ 17,相反,我们还没有获得TS,因为它还没有准备好。如果要使用范围TS或ranges-v3,我们仍然需要此设置。 (2认同)
  • @LF范围是一个库功能。github上有range-v3库,它是标准化的基础,并且受益于此标准化的更改。 (2认同)

dan*_*dam 31

稍后在“注释”中进行解释:

从C ++ 17开始,begin_expr和end_expr的类型不必相同...

而你不能用:

auto __begin = begin_expr, __end = end_expr;
Run Code Online (Sandbox Code Playgroud)