There is a range-based for loop with the syntax:
for(auto& i : array)
It works with constant arrays but not with pointer based dynamic ones, like
int *array = new int[size]; for(auto& i : array) cout
It gives errors and warnings about failure of substitution, for instance:
Error] C:\Users\Siegfred\Documents\C-Free\Temp\Untitled2.cpp:16:16: error: no matching function for call to 'begin(int*&)'
How do I use this new syntax with dynamic arrays?
To make use of the range-based for-loop you have to provide either begin()
and end()
member functions or overload the non-member begin()
and end()
functions. In the latter case, you can wrap your range in a std::pair
and overload begin()
and end()
for those:
namespace std { template T* begin(std::pair const& p) { return p.first; } template T* end(std::pair const& p) { return p.second; } }
Now you can use the for-loop like this:
for (auto&& i : std::make_pair(array, array + size)) cout
Note, that the non-member begin()
and end()
functions have to be overloaded in the std
namespace here, because pair
also resides in namespace std
. If you don't feel like tampering with the standard namespace, you can simply create your own tiny pair class and overload begin()
and end()
in your namespace.
Or, create a thin wrapper around your dynamically allocated array and provide begin()
and end()
member functions:
template struct wrapped_array { wrapped_array(T* first, T* last) : begin_ {first}, end_ {last} {} wrapped_array(T* first, std::ptrdiff_t size) : wrapped_array {first, first + size} {} T* begin() const noexcept { return begin_; } T* end() const noexcept { return end_; } T* begin_; T* end_; }; template wrapped_array wrap_array(T* first, std::ptrdiff_t size) noexcept { return {first, size}; }
And your call site looks like this:
for (auto&& i : wrap_array(array, size)) std::cout
Example
You can't use range-for-loop with dynamically allocated arrays, since compiler can't deduce begin and end of this array. You should always use containers instead of it, for example std::vector
.
std::vector v(size); for(const auto& elem: v) // do something
You can't perform a range based loop over a dynamically allocated array because all you have is a pointer to the first element. There is no information concerning its size that the compiler can use to perform the loop. The idiomatic C++ solution would be to replace the dynamically allocated array by an std::vector
:
std::vector arr(size); for(const auto& i : arr) std::cout
A range based for loop does work for std::array
objects. You have to look over the array instance (arr
), not the type (array
):
std::array arr; for(const auto& i : arr) std::cout
See this page http://www.codeproject.com/Articles/570638/Ten-Cplusplus11-Features-Every-Cplusplus-Developer and find the chapter "non-member begin() and end()". This could be what you want to achieve.