考虑标准算法,比如说std::for_each.
template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f);
Run Code Online (Sandbox Code Playgroud)
据我所知,实际上并没有要求两个论点的相对状态InputIterator.
这是否意味着以下技术上有效?还是未定义?我可以实际期望它做什么?
std::vector<int> v{0,1,2,3,4};
std::for_each(
v.begin()+3, // range [3,0)
v.begin(),
[](int){}
);
Run Code Online (Sandbox Code Playgroud)
geordi告诉我:
错误:函数需要有效的迭代器范围[__ 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){}
);
Run Code Online (Sandbox Code Playgroud)
AnT*_*AnT 21
该标准明确要求last迭代器可以从first迭代器访问.这意味着通过递增first一个应该能够最终命中last.
24.1迭代器要求
...
6迭代器
j被称为从一个迭代可达i当且仅当存在的表达的应用程序的有限序列++i,使i == j.如果j可以从i,它们引用相同的容器.7在数据结构上运行的大多数库的算法模板都有使用范围的接口.范围是一对指定计算开始和结束的迭代器.范围
[i, i)是空的范围; 通常,范围[i, j)是指数据结构中的元素,从指向的那个元素开始,i但最多但不包括指向的元素j.[i, j)当且仅当j可以从中获取时,范围有效i.将库中的函数应用于无效范围的结果是未定义的.
结果是未定义.
C++ 03标准:25.1.1对于每个和
C++ 11标准:25.2.4对于每个
状态:
template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f);
Run Code Online (Sandbox Code Playgroud)
1效果:将f应用于取消引用[first,last]范围内的每个迭代器的结果,从第一个开始到最后一个 - 1
而另一部分将有效范围定义[first,last)为:
C++ 03标准:24.1迭代器要求和
C++ 11标准:24.2.1迭代器要求
第7段:
在数据结构上运行的大多数库的算法模板都有使用range的接口.范围是一对指定计算开始和结束的迭代器.范围[i,i]是空范围; 通常,范围[i,j]是指数据结构中的元素,以i指向的那个元素开始,直到但不包括j指向的元素.当且仅当j可从i到达时,Range [i,j]才有效.将库中的函数应用于无效范围的结果是未定义的.
记得在某个地方读过这篇文章,只是浏览过:
C++标准库 - 教程和参考 - 作者:Nicolai Josutils
这提到了:
5.4.1范围
调用者必须确保第一个和第二个参数定义有效范围.如果通过迭代元素从一开始就可以到达范围的末尾,则会出现这种情况.这意味着,程序员应该确保两个迭代器都属于同一个容器,并且开头不在末尾.如果不是这种情况,则行为未定义,可能会导致无限循环或禁止内存访问.