1

I'm currently trying to program a function that would find the average of elements in an array of integers in C++.

I've looked at new c++11 for loop causes: "error: ‘begin’ was not declared in this scope" but I don't quite understand the problem and how to fix it.

double avg(int arr[]) {
    double sum = 0;
    int size = 0;
    for (int i : arr) {
        sum += i;
        size += 1;
    }
    return sum / size;
}

It gives me errors that "'begin' was not declared in this scope" and "'end' was not declared in this scope". Could somebody explain why the error is occurring and possible ways to fix it?

James Lee
  • 41
  • 2
  • 3
    `for (int i : arr) {` the problem is the size of arr is unknown. It decays into a pointer. – drescherjm Aug 07 '19 at 17:47
  • 9
    Your array doesn't have a size so for each can't work, use a `std::vector` or `std::array` instead – Alan Birtles Aug 07 '19 at 17:47
  • 4
    You are victim of [`arr` decaying to a pointer](https://stackoverflow.com/questions/1461432/what-is-array-decaying). – user4581301 Aug 07 '19 at 17:47
  • 2
    Use `std::array`, not dumb, regular arrays. Then you wouldn't have the issue you are seeing now. – PaulMcKenzie Aug 07 '19 at 17:49
  • @user4581301 Well the very question OP linked is a pretty good dupe as far as content. Maybe it could use a clearer answer (that mentions containers for example) though. –  Aug 07 '19 at 17:54
  • @James Lee The answer is the question you linked is more or less what I would have said... Can you be more specific about what parts of it you're struggling with? –  Aug 07 '19 at 17:54
  • 1
    Avoid raw C-style arrays. Use `std::array` or `std::vector` *always*. – Jesper Juhl Aug 07 '19 at 17:56
  • For more information , the blurb for range_expression in [cppreference's page on range-based for](https://en.cppreference.com/w/cpp/language/range-for) describes where the `begin` and `end` not being declared in the error messages come from. Pointers cannot have an `end` because of the lack of size, and what's the point of `begin` without `end`? – user4581301 Aug 07 '19 at 18:45

3 Answers3

4

The type int arr[] decays into a raw pointer, and as a result there's no way to get the size of the array it refers to.

Instead of using raw arrays, it'd be better just to use either std::vector:

double avg(std::vector<int> const& v) {
    double sum = 0;
    for(int i : v) 
        sum += i;
    return sum / v.size();
}

Or std::array, which acts like a C-array but is copyable and doesn't decay into a pointer:

template<size_t N>
double avg(std::array<int, N> const& arr) {
    double sum = 0;
    for(int i : arr) {
        sum += i;
    return sum / N;
}

Or, if you really have to use arrays, pass the size as a parameter:

double avg(int arr[], size_t size) {
    double sum = 0;
    for(int i = 0; i < size; i++) {
        sum += arr[i];
    }
    return sum / size;
}

Leveraging the C++ standard library

The C++ standard library has a lot of useful functions, and one of them, accumulate, does the job perfectly. It takes a begin and end iterator, as well as the initial value, and computes the sum over the range:

#include <numeric>

double avg(std::vector<int> const& v) {
    return std::accumulate(v.begin(), v.end(), 0.0) / v.size();
}

double avg(int[] arr, size_t size) {
    return std::accumulate(arr + 0, arr + size, 0.0) / size;
}
Community
  • 1
  • 1
Alecto Irene Perez
  • 10,321
  • 23
  • 46
3

Functions may not take arrays as parameters. You get a pointer there. Though you can pass a reference to an array to a function as a parameter. Here is an example:

#include <iostream>

template <typename T, auto n>
void print(const T(&arr)[n]) {
  for (auto&& t : arr) {
    std::cout << t << ' ';
  }
  std::cout << '\n';
}

int main() {
  int arr[]{ 1, 2, 3, 4, 5 };
  print(arr);
}

Output:

1 2 3 4 5
Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93
1

If you want to actually pass an array, not switch to using a vector you can do it with a template function parametrized on the size of the array i.e.

template <int N>
double avg(int (&arr)[N] ) {
    double sum = 0;
    int size = 0;
    for (int i : arr) {
        sum += i;
        size += 1;
    }
    return sum / size;
}

int main()
{
    int ary[] = { 1,2,3,4,5,6 };

    std::cout << avg(ary);
}
jwezorek
  • 8,592
  • 1
  • 29
  • 46