Array iterators

Array, pointers and iterators

Consider a typical operation of outputting an array of data to the screen:

const char *users[] = { "Alice", "Bob", "Charlie" }; 

for(int i = 0; i < 3; ++i)
  std::cout << users[i] << "\n";

This can be performed in a more functional way by using algorithms and iterators:

std::copy(users, users + 3,
          std::ostream_operator<const char*>(std::cout, "\n"));

While marginally longer, this code has the advantage that the output iterator can be replaced with any other (for instance, one that appends to a vector). This relies on the fact that arrays decay to pointers when they are used in a pointer context (be aware that arrays are not pointers, however) and that pointers are iterators.

The main issue, however, is the compile-time constant 3 which represents the size of the array. Should the contents of the array change over time, one may forget to update the constant (even if it’s defined as a named constant on the line that immediately follows the array).

Arrays as template parameters

Luckily, it’s possible to solve this problem by using a template function to extract the size of an array (since the size of the array is part of its type). The code and application:

template <size_t N, typename T>
size_t size(T (&)[N]) { return N; } 

std::copy(users, users + size(users),
          std::ostream_operator<const char*>(std::cout, "\n"));

This works by having a template function that has both the type and the size of an array as template parameters. Since the template parameters are inferred (when possible) from the types of the arguments provided to the function template, both the type (which is ignored) and the size are extracted from an array reference. Even better, unlike the brittle sizeof(users)/sizeof(users[0]) construct, this code will throw a clean compile-time error if for some reason users becomes a pointer and the size is not available anymore.

The next step is obviously:

template <size_t N, typename T>
T* end(T (&a)[N]) { return a + N; } 

std::copy(users, end(users),
          std::ostream_operator<const char*>(std::cout, "\n"));

0 Responses to “Array iterators”


  1. No Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>



1170 feed subscribers
(readers who polled a feed this week)