Can std::begin work with array parameters and if so, how?

Yes, std::begin and std::end can work with parameters that are C style arrays.

The trick is in passing a parameter that’s a C style array. When you specify a 1D array as a normal parameter to a normal function, its type is silently adjusted from “array of T” to “pointer to T”. When you call that function, what gets passed isn’t the array (as an array), but a pointer to the first element of the array.

It is, however, possible to pass an array by reference to a function template:

template <class T, size_t N>
void function(T (&array)[N]) {
   // function body here
}

In this case, where you’re passing an actual array (albeit, by reference) rather than a pointer, you can use std::begin and std::end perfectly well. For example:

template <class T, size_t N>
T sum(T (&array)[N]) { 
    return std::accumulate(std::begin(array), std::end(array), T());
}

Now passing an array is trivial, such as:

int array[] = {1, 2, 3, 4};

auto total = sum(array);

std::begin and std::end themselves are (or at least can be) implemented similarly to sum–the array is passed by reference, so they can look something like this:

template <class T, size_t N>
T *begin(T (&array)[N]) { 
    return array; 
}

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

Note that although these were added to the standard more recently, they don’t require any particularly tricky use of templates, so the implementation above should work fine with a plain old C++98 compiler (and, if memory serves, even with pre-standard compilers such as VC++ 6).

Leave a Comment