0

I have a function in java

static int a2(int[] a)
{
int sumEven = 0;
int sumOdd = 0;

for (int i=0; i<a.length; i++)
{
  if (a[i]%2 == 0)
    sumEven += a[i];
  else
    sumOdd += a[i];
}

return sumOdd - sumEven;
}

I am calling it from main in java like

public static void main()
{
a2(new int[] {1});
a2(new int[] {1, 2});
a2(new int[] {1, 2, 3});
a2(new int[] {1, 2, 3, 4});
a2(new int[] {3, 3, 4, 4});
a2(new int[] {3, 2, 3, 4});
a2(new int[] {4, 1, 2, 3});
a2(new int[] {1, 1});
a2(new int[] {});
}

Where a2 is function and argument is array. This same thing I want to achieve in c++ but I can't pass array to function like I passed in java. It is giving error [error]taking address of temporary array.

In c++, I am doing like that

f((int[4]) {1,2,3,4});

Giving error => [error]taking address of temporary array.

How to achieve this?

Sagar
  • 1,115
  • 2
  • 11
  • 23

4 Answers4

6

Use std::vector instead of dealing with low level array:

int a2( const std::vector<int> &v )
{
    return std::accumulate( v.begin(), v.end(), 0, []( int a, int b ) {
        return a + ( b % 2 ? b : -b );
    } );
}

int main()
{
    a2( { 1, 2, 3 } );
}

live example

Slava
  • 43,454
  • 1
  • 47
  • 90
3

In C/C++, plain function does not have array parameters. Although you can write something like

void f(int a[]) { }

But that a will decay to a pointer instead of an array.

But if you can kind of work around that by using a template

template <typename T, std::size_t N>
void f(const T (&a) [N]) {}

Or as others suggested, std::vector could be a better choice or even std::array.

To use a temporary array, for example, you can do this,

typedef int INTARRAY [];
f (INTARRAY{1, 2, 3, 4});

Note that the declaration of f now is changed to use const T instead of T.

CS Pei
  • 10,869
  • 1
  • 27
  • 46
2

References to arrays work a little differently in C++. The function signature needs to change to something like *Note you can add const to bind to temporaries

int a2(int(&a)[3]){/*..*/}

For an array of size 3. That is, the size must be known at compile-time.

If you'd like to take arrays of different sizes, either change the function to accept a pointer and a size like so (used in a lot of C-style programs):

int a2(int* a, int array_size){/*..*/}

or create a template like CS Pei mentions (probably the best way, and answers your question directly about references to arrays)

template <class T, int N>
int a2(T (&a) [N]) {/*..*/}
AndyG
  • 39,700
  • 8
  • 109
  • 143
1

Here you are

#include <iostream>

template <size_t N>
int f( const int ( &a )[N] )
{
    int sumEven = 0;
    int sumOdd = 0;

    for ( size_t i = 0; i < N; i++ )
    {
        if ( a[i] % 2 == 0 )
            sumEven += a[i];
        else
            sumOdd += a[i];
    }

    return sumOdd - sumEven;
}

int main() 
{
    std::cout << f( {1} ) << std::endl;
    std::cout << f( {1, 2} ) << std::endl;
    std::cout << f( {1, 2, 3} ) << std::endl;
    std::cout << f( {1, 2, 3, 4} ) << std::endl;
    std::cout << f( {3, 3, 4, 4} ) << std::endl;
    std::cout << f( {4, 1, 2, 3} ) << std::endl;

    return 0;
}

The program output is

1
-1
2
-2
-2
-2

As for used by you expression as an argument as for example here

f((int[4]) {1,2,3,4});

then

( int[4] ){ 1, 2, 3, 4 }

is a compound literal that is defined in C but is not defined in C++. If to write a C program that uses compound literals then the function has to have a second parameter that specifies the number of elements in the array.

For example

#include <stdio.h>

int f( int a[], size_t n )
{
    int sumEven = 0;
    int sumOdd = 0;

    for ( size_t i = 0; i < n; i++ )
    {
        if ( a[i] % 2 == 0 )
            sumEven += a[i];
        else
            sumOdd += a[i];
    }

    return sumOdd - sumEven;
}

int main( void ) 
{
    printf( "%d\n", f( ( int[] ){1}, 1 ) );
    printf( "%d\n", f( ( int[] ){1, 2}, 2 ) );

    return 0;
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335