它是否定义为为C++标准算法提供反转范围
Is it defined to provide an inverted range to C++ standard algorithms?
考虑标准算法,比如说,std::for_each
.
template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f);
据我所知,实际上对两个InputIterator
论点的相对状态没有要求。
这是否意味着以下内容在技术上是有效的?还是未定义?我能现实地期望它做什么?
std::vector<int> v{0,1,2,3,4};
std::for_each(
v.begin()+3, // range [3,0)
v.begin(),
[](int){}
);
乔迪告诉我:
错误:函数需要有效的迭代器范围 [__first、__last(。[+ 13 条废弃线路]
但我无法判断此调试诊断的合规性。
当试图学究地确定以下行为的定义有多明确时,我想出了这个问题:
std::vector<int> v; // <-- empty
std::for_each( // <-- total no-op? stated or just left to implication?
v.begin(),
v.end(),
[](int){}
);
该标准明确要求last
迭代器可从first
迭代器访问。这意味着通过增加first
应该能够最终达到last
。
24.1 迭代器要求
。
6 迭代器
j
称为可从迭代器访问i
当且仅当 表达式的应用序列有限++i
使i == j
.如果可以从i
访问j
,则它们引用相同的 容器。7 大多数库的算法模板都可以运行 在数据结构上具有使用范围的接口。范围是一对 指定计算开始和结束的迭代器。 范围
[i, i)
是空范围;通常,[i, j)
指的范围 数据结构中的元素,从i
,但不包括j
指出的那个。范围[i, j)
为 当且仅当可从i
访问j
时有效。的结果 将库中的函数应用于无效范围是 定义。
结果是未定义。
C++03 标准:25.1.1 对于每个和
C++11 标准:25.2.4 对于每个国家:
template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f);
1 效果:将 f 应用于取消引用范围 [first, last( 中每个迭代器的结果,从 从第一个到最后一个 - 1
而另一部分将有效范围[first,last)
定义为:
C++03 标准:24.1 迭代器要求和
C++11 标准:24.2.1 迭代器要求
第7段:
大多数对数据结构进行操作的库算法模板都具有使用范围的接口。范围是一对迭代器,用于指定计算的开始和结束。 范围 [i, i( 是空范围;通常,范围 [i, j( 是指数据结构中的元素,从 i 指向的元素开始,一直到 j 指向的元素,但不包括 j 指向的元素。范围 [i, j( 有效,当且仅当 j 可从 i 访问时。 将库中的函数应用于无效范围的结果是未定义的。
记得在某处读过这篇文章,只是浏览了一下:
C++ 标准库 - 教程和参考 - 尼古拉·乔斯蒂尔斯
这在以下位置有提及:
5.4.1 范围
调用方必须确保第一个和第二个参数定义有效范围。如果可以通过遍历元素从一开始就到达范围的末尾,则会出现这种情况。这意味着,程序员有责任确保两个迭代器属于同一个容器,并且开头不落后于结尾。如果不是这种情况,则行为未定义,可能会导致无限循环或禁止的内存访问。
这是否意味着以下内容在技术上是有效的?还是 定义?我能现实地期望它做什么?
不,不是。当for_each
增加迭代器时,您的代码将表现出未定义的行为,并且该迭代器将指向end
并且没有什么可以取消引用的(好吧,此时获得未定义的行为就足够了,所以谈论过去的结束是没有意义的(!
这由标准"迭代器要求"的第 24.1 节解释:
迭代器
j
称为可从迭代器i
访问当且仅当表达式++i
的有限应用序列使i == j
。如果j
可以从i
访问,则它们引用同一容器。。
范围
[i, j)
有效当且仅当可从i
访问j
。将库中的函数应用于无效范围的结果是未定义的。
所以v.begin() + 3
可以从v.begin()
到达,但不能相反。因此,[v.begin()+3, v.begin())
不是有效范围,并且您对for_each
的调用未定义。
该标准定义了采用范围的函数的复杂性约束。在for_each
的特定情况下(C++标准中的 25.2.4(:
复杂性:精确
f
last - first
次应用
因此,在您的示例中,它实际上是一个无操作。
- 基于多维标准::数组的范围
- 标准是否阻止在可变参数模板中使用足够小的文本值缩小文本转换范围
- 为什么我的 RLE 代码显示标准超出 C++ 的范围?
- 满足标准::范围::范围概念
- 标准范围::流::SGETC
- C++标准强加的整数范围
- 如何将标准::字符串拆分为标准::string_views的范围 (v3)
- 是否存在用于按以下方式对两个范围进行排序和分区的标准算法?
- 强制标准名称空间的命名空间范围
- 标准容器封装和基于范围的 for 循环
- 有没有一种标准方法来确保一段代码在全局范围内执行
- 矢量下标超出范围和标准 c++ 库超出范围C++
- 通过引用查找调用范围的标准引用是什么
- 是否有使用谓词比较两个范围的标准方法
- 标准::队列的基于范围的循环
- 有一个标准的算法可以在一个范围内迭代吗
- 在C++标准中,我可以在哪里找到对全局范围内调用函数的支持
- C++ 中的整数范围 - 当标准尚不存在时我该怎么办
- 标准::矢量::擦除无效范围
- 是否有将范围移动到矢量中的标准方法