在单个左值上迭代

Iterating over a single lvalue

本文关键字:迭代 单个左      更新时间:2023-10-16

我想把一个左值传递给一个需要一对迭代器的函数,让它像我把一对迭代器传递给只包含这个值的范围一样。

我的方法如下:

#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中似乎是正确的,但我想知道这是否真的是定义的行为,是否存在任何潜在的问题?

是的,这是定义的行为。首先我们有来自[expr.add]/4

出于这些运算符的目的,指向非数组对象的指针的行为与指向长度为1的数组的第一个元素的指针相同,其中对象的类型为其元素类型。

因此,将单个对象视为长度为1的数组。然后我们有[expr.add]/5

[…]此外,如果表达式p指向数组对象的最后一个元素,则表达式(p)+1指向数组对象最后一个元件后的一个,并且如果表达式Q指向数组对象最近一个元件前的一个元件,则表达式"Q"-1指向数组对象最后一个元件如果指针操作数和结果都指向同一数组对象的元素,或者指向数组对象最后一个元素之后的元素,则求值不应产生溢出否则,行为未定义。

强调矿

因此,由于第一个数组元素也是最后一个数组元素,并且在最后一个元素上加1可以得到经过对象的一个,所以这是合法的。