Tryer Tryer - 23 days ago 7
C++ Question

Using a function pointer from one class in a function of another class

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.

Answer Source

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]);
}