Incrementing pointers is idiomatic C++, because pointer semantics reflect a fundamental aspect of the design philosophy behind the C++ standard library (based off of Alexander Stepanov's STL)
The important concept here, is that the STL is designed around containers, algorithms, and iterators. Pointers are simply iterators.
Of course, the ability to increment (or add/subtract from) pointers goes back to C. A lot of C-string manipulation algorithms can be written simply using pointer arithmetic. Consider the following code:
char string1 = "abc";
char* src = string1;
char* dest = string2;
while ((*dest++ = *src++));
This code uses pointer arithmetic to copy a null-terminated C-string. The loop automatically terminates when it encounters the null.
With C++, pointer semantics are generalized to the concept of iterators. Most standard C++ containers provide iterators, which can be accessed via the
end member functions. Iterators behave like pointers, in that they can be incremented, dereferenced, and sometimes decremented or advanced.
To iterate over an
std::string, we would say:
std::string s = "abcdef";
std::string::iterator it = s.begin();
for (; it != s.end(); ++it) std::cout << *it;
We increment the iterator just like we would increment a pointer to a plain C-string. The reason this concept is powerful is because you can use templates to write functions that will work for any type of iterator that meets the necessary concept requirements. And this is the power of the STL:
std::string s1 = "abcdef";
std::copy(s1.begin(), s1.end(), std::back_inserter(buf));
This code copies a string into a vector. The
copy function is a template that will work with any iterator that supports incrementing (which includes plain pointers). We could use the same
copy function on a plain C-string:
const char* s1 = "abcdef";
std::copy(s1, s1 + std::strlen(s1), std::back_inserter(buf));
We could use
copy on an
std::map or a
std::set or any custom container that supports iterators.
Note that pointers are a specific type of iterator: random access iterator, which means they support incrementing, decrementing, and advancing with the
- operator. Other iterator types only support a subset of pointer semantics: a bidirectional iterator supports at least incrementing and decrementing; a forward iterator supports at least incrementing. (All iterator types support dereferencing.) The
copy function requires an iterator that at least supports incrementing.
You can read about different iterator concepts here.
So, incrementing pointers is an idiomatic C++ way to iterate over a C-array, or access elements/offsets in a C-array.