我想将一个左值传递给一个需要一对迭代器的函数,并且它就像我将一对迭代器传递给只包含这个值的范围一样。
我的方法如下:
#include <iostream>
#include <vector>
template<typename Iter>
void iterate_over(Iter begin, Iter end){
for(auto i = begin; i != end; ++i){
std::cout << *i << std::endl;
}
}
int main(){
std::vector<int> a{1,2,3,4};
iterate_over(a.cbegin(), a.cend());
int b = 5;
iterate_over(&b, std::next(&b));
}
这似乎在g ++ 5.2中正常工作,但我想知道这是否是实际定义的行为以及是否存在任何潜在问题?
答案 0 :(得分:11)
是的,这是定义的行为。首先我们来自[expr.add] / 4
出于这些运算符的目的,指向非阵列对象的指针与指向长度为1的数组的第一个元素的指针的行为相同,其中对象的类型为其元素类型。
因此,单个对象被视为长度为1的数组。然后我们有[expr.add] / 5
[...] 此外,如果表达式P指向数组对象的最后一个元素,则表达式(P)+1指向一个超过数组对象的最后一个元素并且如果表达式Q指向一个超过数组对象的最后一个元素的表达式,则表达式(Q)-1指向数组对象的最后一个元素。 如果指针操作数和结果都指向同一个数组对象的元素,或者指向数组对象的最后一个元素,则评估不应产生溢出; 否则,行为未定义。
强调我的
因为第一个数组元素也是最后一个数组元素,并且向最后一个数组元素添加1会给你一个超过该对象的元素,这是合法的。