Misconception
At least in C++ community, index is not considered to be iterator. In fact, using std::iterator_traits<>
on int
will cause compilation error. Though pointer is iterator, but not every iterator is a pointer.
C
Usually people prefer iterators if they're easily accessible and simplify the problem. IIRC even in C people prefer \$[begin, end)\$ ranges, e.g. one past the end of the array. It is specifically allowed in C standard to go one past the end of array, but no further.
Application of the concepts above will give you what Edward covered in the post.
Iterators
One can #include <iterator>
to get access to std::begin()
and std::end()
. Usually iterators are paired with #include <algorithm>
to provide access to higher level algorithms. Generally one should use higher level algorithms if they don't need control the algorithms take away from them.
Algorithms
std::copy(std::begin(arr), std::end(arr), std::ostream_iterator<int>{std::cout, " "});
Now, that doesn't do the same thing as in your post (it doesn't print address), but it is what I use on a daily basis. My IDE has special shortcuts for this, especially for std::begin
/std::end
combination, and for std::ostream_iterator<int>
.
The array filling loop can be rewritten using std::iota
(from <numeric>
):
std::iota(std::begin(arr), std::end(arr), 0);
Why standard algorithms and iterators?
The combination makes your code very flexible. If you'll decide to change the type to std::vector<int>
, or std::list<int>
(please don't use list unless there is a serious reason for it), your code will still work as expected.
constexpr
const
is good, but constexpr
will be better in this case. The feature is specifically designed for these use cases. Basically, just add expr
at the end of const
.
Puttin together
With all of the above, the code becomes:
#include <iostream> #include <iterator> #include <algorithm> #include <numeric> #include <array> int main() { constexpr size_t size = 10; std::array<int, size> arr; std::iota(std::begin(arr), std::end(arr), 0); std::copy(std::begin(arr), std::end(arr), std::ostream_iterator<int>{std::cout, " "}); }
Further use of standard library
C++11 has <array>
, which is inside plain array, e.g. it doesn't have other non-static members, alignment is handled correctly as well. The syntax would be:
std::array<int, size> arr;
The benefits it gives are:
No decaying into pointer
Store their sizes (it is constexpr)
mimics std::vector
's interface
tuple operations can be applied on std::array
Drawbacks:
(ptrLastElement - curr) >= 0
looks like a less readable version ofcurr <= ptrLastElement
\$\endgroup\$curr <= ptrLastElement
is definitely more readable and it doesn't require computation.\$\endgroup\$