Can std::begin work with array parameters and if so, how?
arrays, c++, iterator, std, stl
Solution
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).
Problem
I have trouble using `std::begin()` and `std::end()` (from the `iterator` library) with c-style array parameters. ``` void SetOrigin(const double i_point[3]) { Vector v; std::copy( std::begin(i_point), std::end(i_point), v.begin()); this->setOrigin(v); } ``` This results in the following error with Visual Studio 2010 (and similar for end): ``` error C2784: '_Ty *std::begin(_Ty (&)[_Size])' : could not deduce template argument for '_Ty (&)[_Size]' from 'const double []' 1> c:\program files (x86)\microsoft visual studio 10.0\vc\include\xutility(995) : see declaration of 'std::begin' ``` Changing the parameter to non-const gives same result. Trying to specify the parameter as ``` ... std::begin<const double, 3>(i_point), std::end<const double, 3>(i_point), ... ``` Gives: ``` error C2664: '_Ty *std::begin<const double,3>(_Ty (&)[3])' : cannot convert parameter 1 from 'const double []' to 'const double (&)[3]' ``` Is it just not possible to use `std::begin` on array parameters because they decay to pointers? Is there a trick to get around this or is it best just to not use the iterator functions on array parameters?