0

I have two overloaded functions: "ChooseElements", which chooses elements from passed array, and "SortElements", which sorts elements of passed array. One pair works with INT data, and another one with FLOAT.

int * ChooseElements(int * X, int n, int & m)
{
    int * Y = NULL;
    for (int i = 0; i < n; i++)
    {
        if (X[i] > 0)
        {
            if (Y == NULL)
            {
                m = 1;
                Y = new int[1];
                Y[0] = X[i];
            }
            else
            {
                m++;
                Y = (int *)realloc(Y, sizeof(int) * m);
                Y[m - 1] = X[i];
            }
        }
    }

    return Y;
}

float * ChooseElements(float * X, int n, int & m)
{
    float * Y = NULL;
    for (int i = 0; i < n; i++)
    {
        if (X[i] > 0)
        {
            if (Y == NULL)
            {
                m = 1;
                Y = new float[1];
                Y[0] = X[i];
            }
            else
            {
                m++;
                Y = (float *)realloc(Y, sizeof(float) * m);
                Y[m - 1] = X[i];
            }
        }
    }

    return Y;
}

and

int * SortElements(int m, int *& Y)
{
    for (int i = 1; i < m; i++)
    {
        for (int j = 0; j < m - i; j++)
        {
            if (Y[j] > Y[j + 1])
            {
                int Temp = Y[j];
                Y[j] = Y[j + 1];
                Y[j + 1] = Temp;
            }
        }
    }

    return Y;
}

float * SortElements(int m, float *& Y)
{
    for (int i = 1; i < m; i++)
    {
        for (int j = 0; j < m - i; j++)
        {
            if (Y[j] > Y[j + 1])
            {
                float Temp = Y[j];
                Y[j] = Y[j + 1];
                Y[j + 1] = Temp;
            }
        }
    }

    return Y;
}

What I want to do is pass first function as argument to second one. Like that:

int n, m;
int * X = NULL, * Y = NULL;

/* ...
Some code in which n and X are initialized
... */

Y = SortElements(m, ChooseElements(X, n, m));

However, when I try to do that, Visual Studio 2017 tells me:

no instance of overloaded function "SortElements" matches the argument list

argument types are: (int, int *)

If I do this instead:

Y = ChooseElements(X, n, m);
Y = SortElements(m, Y);

everything works fine.

If I remove overloads and leave only INT pair and once again try

int n, m;
int * X = NULL, * Y = NULL;

/* ...
Some code in which n and X are initialized
... */

Y = SortElements(m, ChooseElements(X, n, m));

I get another problem:

int *ChooseElements(int *X, int n, int &m)

initial value of reference to non-const value must be an lvalue

What am I doing wrong? My teacher asks for a function which uses another function as an argument. What I have written does not work, and I have no idea what could be done here.

Mgetz
  • 5,108
  • 2
  • 33
  • 51
BEEET Hvcw
  • 49
  • 4
  • Drop the reference from array pointer in `SortElements()`: `int * SortElements(int m, int *Y)`. Actually, it is not necessary as you don't want to re-allocate the array in `SortElements()`. (The contents of array `Y` might be changed but not it's start address.) – Scheff's Cat May 12 '18 at 11:57
  • With the above suggested change, it will compile without complaints: [**ideone**](https://ideone.com/fpyMUP). – Scheff's Cat May 12 '18 at 12:04
  • I feel a bit bad about the `m` in `SortElements(m, ChooseElements(X, n, m));`. What if 1st `m` is passed as argument before 2nd `m` is updated in `ChooseElements(X, n, m)`? I found [SO: Order of evaluation in C++ function parameters](https://stackoverflow.com/q/2934904/7478597) regarding this. The answers rather enforces my bad feeling... – Scheff's Cat May 12 '18 at 12:10
  • @Scheff that worked! Thank you a lot! I wonder how have I missed that. – BEEET Hvcw May 12 '18 at 12:11
  • @Scheff you are right, that is not good at all. I will try to figure it out. – BEEET Hvcw May 12 '18 at 12:14
  • Passing `m` by reference in `SortElements()` is probably something which can at least work around the "order of evaluation" issue. A better design would group size and array pointer together so that both can be passed/returned as bundle: e.g. `struct ArrayInt { int n; int *data; }`. Now, this design is close to [`std::vector`](http://en.cppreference.com/w/cpp/container/vector) (which does the same with even more features). However, if your teacher requires a solution without `std` templates than you may consider the `ArrayInt` idea. – Scheff's Cat May 12 '18 at 12:16

1 Answers1

0

In your int * SortElements(int m, int *& Y) function you are using : int *& Y. So you have a reference to a int pointer. My guess is that you don't need that. You can just use int * Y as a parameter as a solution.

Int *& Y - needs an lvalue(like your variable Y) but your ChooseElements function returns only a temporary object(rvalue) because you are returning by value.

scrapper
  • 361
  • 2
  • 6