Single value iteration

I would like to pass one lvalue to a function that expects a pair of iterators, and so that it acts as if I passed a pair of iterators to a range containing only this value.

My approach is as follows:

#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)); } 

It seems to work correctly in g ++ 5.2, but I wonder if this behavior is really defined and are there any potential problems?

+6
source share
1 answer

Yes, this is a defined behavior. First we are from [expr.add] / 4

For these operators, a pointer to a nonarray object behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type.

Thus, one object is considered as an array of length 1. Then we have [expr.add] / 5

[...] In addition, if the expression P points to the last element of the array object, the expression (P) +1 indicates one after the last element of the array object, and if the expression Q indicates one after the last element of the array object, expression (Q) -1 points to the last element of an array object. If both pointer operands and the result point to elements of the same array object or one after the last element of the array object, the evaluation should not lead to overflow; otherwise the behavior is undefined.

Emphasis on mine

So, since the first element of the array is also the last element of the array, and adding 1 to the last element of the array gives you one after the object, it is legal.

+11
source

All Articles