0

To pass by reference the C-style array as a parameter to a function, one needs to send the array size as a parameter to the function as well. The below code shows a function that accepts an array as pass by reference along with its size. Q1) Is there a way, we can pass arrays by reference without passing its size as well? Q2) If I were to overload the below function get_num_of_even_digited_input() to accept an array container (std::array) as the first parameter, what would the function prototype look like? (I mean how do I mention the size_t parameter for the array? Will it be int get_num_of_even_digited_input(array<int,??> )

int get_number_of_digits(int in_num)
{
    int input = in_num, rem = -1, dividend = -1, dig_count = 0;
    
    while(input)
    {
        dig_count++;
        dividend = input % 10;
        input = input/10;
    }

    return dig_count;
}

int get_num_of_even_digited_input(int arr[], int size_arr)
{
    int arrsize = 0, i = 0, count_of_evendigited_num = 0, count_of_dig = 0;
    arrsize = size_arr;

    for(i = 0; i < arrsize; i++, arr++)
    {
        count_of_dig = get_number_of_digits(*arr);
        if(count_of_dig % 2 == 0)
        {
            count_of_evendigited_num++;
        }
    }

    return count_of_evendigited_num;
}

void main()
{
    int array2[] = {23, 334, 4567, 1, 259};
    int sizearr2 = sizeof(array2)/sizeof(int);

    array<int, 6> array3 = {23, 5677, 564, 342, 44, 56778};

    cout << "Count of even digited numbers in array2[] : " << get_num_of_even_digited_input(array2, sizearr2) << endl;
    cout << "Count of even digited numbers in array3[] : " << get_num_of_even_digited_input(array3, array3.size) << endl; // HOW IS THIS FUNCTION PROTOTYPE GOING TO LOOK LIKE??
}
Manasa
  • 43
  • 6
  • Questions asking for homework help must include a summary of the work you've done so far to solve the problem, and a description of the difficulty you are having solving it. Please read [How to ask homework questions](https://meta.stackoverflow.com/questions/334822/how-do-i-ask-and-answer-homework-questions) and [edit] your post. – Nick Aug 09 '20 at 07:02
  • You should not do [`void main()`](https://stackoverflow.com/questions/204476/what-should-main-return-in-c-and-c) – Waqar Aug 09 '20 at 07:22

4 Answers4

1

Yes:

template<auto size>
void foo(int (&arr)[size]);

The STL way of doing this would be to pass begin/end iterators:

template<typename Iter>
void foo(Iter begin, Iter end);

Or use std::span in C++20.

Ayxan Haqverdili
  • 17,764
  • 5
  • 27
  • 57
  • 1
    You could also pass the array by const-reference. `foo(const int (&arr)[size]);`. But that will only allow normal arrays. – MyClass Aug 09 '20 at 07:08
  • @MyClass I left const out because this is a declaration and the definition could change the contents of the array. OP gets to decide – Ayxan Haqverdili Aug 09 '20 at 07:15
1

Is there a way, we can pass arrays by reference without passing its size as well?

It's not mandatory to pass the array size. You can pass the array only, but you have to be sure you don't operate out-of-bound. The size there is to help the user of the function to do just that (ie operating in safe manner).

Alternatively, and better, use std::vector instead. You should never to worry about the size anymore as that information comes from the input vector itself.

what would the function prototype look like?

When you use vector, the prototype can be:

int get_num_of_even_digited_input(std::vector<int>& param)

As said you don't need to pass the size anymore, because you can always use param.size() to find out how many items are there.

Also if you don't change the param inside that function, then use const std::vector<int>& param instead.

artm
  • 16,141
  • 4
  • 27
  • 46
1

You can make the parameter pass-by-reference, then no need to pass the size of array. (When passing by-reference, raw array won't decay to pointer and its size is reserved.) And also make the function template, then it can work with both raw arrays and std::array.

template <typename T>
int get_num_of_even_digited_input(const T& arr)
{
    int count_of_evendigited_num = 0;

    // I use range-based for loop here
    // you can get the size of the array as std::size(arr) if necessary
    // it works with raw arrays and std::array too
    for (auto e : arr)
    {
        if(get_number_of_digits(e) % 2 == 0)
        {
            count_of_evendigited_num++;
        }
    }

    return count_of_evendigited_num;
}
songyuanyao
  • 147,421
  • 15
  • 261
  • 354
0

In C++ array size is a compile time concept because the size of the array is part of its type so it doesn't really makes sense to say that you have a function accepting arrays of different sizes at runtime.

You can write a function template that will accept arrays and that will expand to the specific version accepting a reference/pointer for a given array size. This is rarely a good idea because if you have say 10 different sizes for your arrays your compiled code would end up with 10 different copies of the same function. What the template strange syntax is saving you from is just writing those copies by hand.

What is normally done is writing a function that accepts a pointer to the first element and the number of elements at runtime, and then a small template wrapper that will just expand the call so that the size doesn't need to be passed explicitly:

int sum(const int *x, int n) {
    int s = 0;
    for (int i=0; i<n; i++) {
        s += x[i];
    }
    return s;
}

template<int N>
int sum(const int (&x)[N]) {
    return sum(x, N);
}

int foo() {
    int x[] = {1,2,3,4};
    return sum(x);
}

In the above code there will be only one copy of the function actually computing the sum of the elements and the template trick is used just to replace

sum(x);

with

sum(&x[0], 4);

automatically.

Even more frequently C arrays are replaced with std::vector for dynamic size containers and std::array for static size containers (the main advantage of std::array is that is a "normal" type that is handled like other C++ types and for example can be passed by value or can be returned from a function, something that doesn't work with C arrays).

6502
  • 104,192
  • 14
  • 145
  • 251