0

I have looked at the following threads, but they do not seem to help resolve the issue:

Function pointer to member function - this thread does not help because the access is made within main and not another class

one class should invoke method of another class using a function pointer - I could not follow the accepted answer as it is not clear to me how to use <functional> header.

I have a Useful Function class, UF, in which I declare and define all common utility functions for my program. One of these functions is

int UF::compar_dbl_asc(const void *a, const void *b)//comparator for sorting 
{                                                   //array of double in ascending order
    int aa = *((int *)a), bb = *((int *)b);
    if (base_arr_dbl[aa] < base_arr_dbl[bb])
        return -1;
    if (base_arr_dbl[aa] == base_arr_dbl[bb])
        return 0;
    if (base_arr_dbl[aa] > base_arr_dbl[bb])
        return 1;
}

This is a comparator function that I intend to use within qsort() for sorting doubles in ascending order.

Within UF class definition, I also have double* base_arr_dbl; as a declaration. This is the array of values (doubles) that qsort will use.

Now, in a different class of mine named SEP, I have a function, fn1 wherein I would like to have base_arr_dbl point to a local (to fn1) double array and I would like to invoke qsort using the comparator function in UF. To be very specific although this is possibly not needed, I do not sort the actual values' array, but will sort an array of indices sortedindices[], such that sortedindices[0] will hold the index of the smallest entry in base_arr_dbl[] array. That is, the sorted order is base_arr_dbl[sortedindices[0]], base_arr_dbl[sortedindices[1]], etc.

So, I do this:

void SEP::fn1(UF *uf) {

    double ratio[100];
    //populate ratio's entries
    //Now, sort ratio's entries.
    uf->set_base_arr_dbl(ratio); //This function is defined as
   //void UF::set_base_arr_dbl(double *ptr) { base_arr_dbl = ptr; }
    qsort(sortedindices, 100, sizeof(double), uf->compar_dbl_asc);

}

However, the line qsort(sortedindices, 100, sizeof(double), uf->compar_dbl_asc); throws the following compile time error:

error C3867: 'USEFUL_FUNCTIONS::compar_dbl_asc': non-standard syntax; use '&' to create a pointer to member

I tried having &uf->compar_dbl_asc but that gives the error:

error C2276: '&': illegal operation on bound member function expression

Any way to help resolve this is appreciated.

11
  • 3
    "I have a Useful Function class, UF, in which I declare and define all common utility functions for my program" That sounds like such a horrible design Commented Sep 25, 2017 at 19:16
  • 3
    Why not have a namespace instead? Do your utility functions require state? Commented Sep 25, 2017 at 19:17
  • 2
    And otherwise, can't these utility functions be static within the class so that you wouldn't require an instance? Commented Sep 25, 2017 at 19:18
  • @AndyG I am not knowledgeable about what it means for functions to require states. Could you elaborate? Also, would that help resolve this function pointer issue? Commented Sep 25, 2017 at 19:19
  • 2
    @Tryer: I mean member variables. Does UF have member variables, and if so, why? It seems like you have a design problem that you should solve first. We could help you write code that would theoretically work in this design, but it would encourage bad design principles. Commented Sep 25, 2017 at 19:20

1 Answer 1

2

As the compiler clearly tells in the error messages, neither uf->compar_dbl_asc nor &(uf->compar_dbl_asc) is appropriate for use as an argument to qsort.

You can use compar_dbl_asc as an argument to qsort using one of the following approaches.

  1. Make compar_dbl_asc a static member function of the class.
  2. Better yet, create a namespace for your app and define compar_dbl_asc in the namespace. UF could be that namespace unless it must be a class for some other reasons.

Another choice would be forego use of qsort in favor of std::sort. The latter gives you more options. You can use a functor or a lambda function when you use std::sort, which will allow you to use UF::compar_dbl_asc.

std::sort(sortedindices, sortedindices+100,
          [=uf](int a, int b) { return uf->compar_dbl_asc(a, b); });

One thing to note is that if you choose the last approach, the signature of UF::compar_dbl_asc can be changed to a more user friendly variation.

bool UF::compar_dbl_asc(int a, int b)
   return (base_arr_dbl[a] < base_arr_dbl[b]);
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks. Let me look into namespaces. I am guessing, like classes, namespaces would also be declared in the main header file?
@R Sahu I think I will choose option 2, of namespace. Could you indicate what the syntax of qsort(sortedindices, 100, sizeof(double), uf->compar_dbl_asc); would have to be changed to? I will declare UF as the name of the namespace. I don't need to have it as a class.
@Tryer, use UF::compar_dbl_asc.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.