I know we can iterate through an array passed as an argument in this way:
// NO ERROR
void fun(int *a, int n){
    for(int i=0; i<n; i++)
        cout<<a[i];
}
But, is there any way I could iterate through an array using a for-each loop inside a function like this?
// ERROR
void fun(int *a, int n){
    for(auto x:a)
        cout<<x;
}
                Iterate array-like objects using forEach In order to iterate over its items, you have to call indirectly forEach() using the call() . The forEach() method is taken from Array.
We can use iteration with a for loop to visit each element of an array. This is called traversing the array. Just start the index at 0 and loop while the index is less than the length of the array.
A pointer is not an array. If you pass a pointer to the first element of an array to a function then its no longer an array, but a pointer.
You can use a range based loop when you pass the array by reference:
#include <iostream>
template <size_t N>
void foo(int (&x)[N]) {
    for (int i : x) std::cout << i << " ";
}
int main() {
    int x[] = {1,2,3};
    foo(x);
}
Output:
1 2 3 
This works, because the range based loop uses std::begin(x) and std::end(x) to get iterators to the begin and end of the array. Pointers don't have a begin or end.
In C++20, you can use std::span:
#include <cstddef>
#include <cstdio>
#include <span>
void foo(int* arr, std::size_t sz) {
  std::span<int> span{arr, sz};
  for (int elm : span) {
    std::printf("%d\n", elm);
  }
}
Or you could make span the input argument in the first place:
void foo(std::span<int> span) {
  for (int elm : span) {
    std::printf("%d\n", elm);
  }
}
If the signature of the function is flexible, I suggest you use the second option.
Pre C++20, here is an implementation of span from GSL. Or make your own wrapper class with begin() and end() functions.
Alternative non-template C++20 solution:
auto range = std::views::counted(arr, sz);
for (auto elm : range) {
The benefit of this compared to std::span is that this is more general and works with any  iterator, not requiring a contiguous iterator such as a pointer.
The benefit of using std::span instead of this is that you can use std::span as the function parameter without making it a template.
Alternative template solution (works pre C++20):
template <class Range>
void foo(const Range& range) {
    for (auto elm : range) {
The benefit of this compared to int (&arr)[N] is that it is much more general. This template works with all ranges.
Besides range-for, you could consider avoiding the loop entirely (works pre C++20):
auto print = [](auto elm) {
    std::cout << elm;
}
std::for_each_n(arr, sz, print);
I recommend this if you don't have C++20, cannot have boost / ranges / GSL libraries for some reason, and cannot have a template.
yes, you can. Just pass the array by reference to a template function:
#include <iostream>
using namespace std;
 
template <size_t N> void foo(int (&arr)[N])
{
    for (auto i:arr)
        cout << i << " ";
}
 
int main()
{
    int array[] = { 5, 17, 3452, 546546, 756756, 75675, 756753, 345, 53};
    foo(array);
    return 0;
}
                        And the real answer:
int made[] = {10 , 2 ,15};
 std::for_each(std::begin(made),std::end(made),[=](auto x){ std::cout << x << std::endl; });
You can parallelize std::for_each with say std::execution::par.
With function code will be:
#include <iostream>
#include <vector>
#include <execution>
void f(int (&made)[3])
{
     std::for_each(std::begin(made),std::end(made),[=](auto x){ std::cout << "and then " << x << std::endl; });
}
int main(int argc , char *argv[])
{
    int made[] = {10 , 2 ,15};
    f(made);
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With