Help with C++ compiler error: int function does not match int (*) function

I’m trying to incorporate some code into a class, but I’m getting an error when I compile in the class I get the error:


argument of type ‘int (circ_sort::)(const void*, const void*)’ does not match ‘int (*)(const void*, const void*)’

The most stripped-down code that I still get the error on is: (the line that’s causing the problem is bolded).


#include <cstdio>
#include <cstdlib>

using namespace std;

class circ_sort
{
   public:
      int Compare( const void* a, const void* b );
      void QSort( void );

   private:
      int         size,
                  nextEntryLocation;
      double   *  circBuffer,
               ** sortedBuffer;
};

int circ_sort::Compare (const void * a, const void * b)
{
}

void circ_sort::QSort( void )
{
   **qsort( sortedBuffer, (size_t) size, sizeof( double* ), Compare );**
}

int main( void )
{
   return 0;
}

Compare this with a function that compiles fine


#include <cstdio>
#include <cstdlib>

using namespace std;

int Compare (const void * a, const void * b);

int main( void )
{
   int         size,
               nextEntryLocation;
   double   *  circBuffer,
            ** sortedBuffer;

   qsort( sortedBuffer, (size_t) size, sizeof( double* ), Compare );

   return 0;
}

int Compare (const void * a, const void * b)
{
}

Of course, neither of these programs will run in the state they are in, but I just need to get past this compiler error. For reference, information about qsort is here.

qsort wants a pointer to a regular C function, but you are giving it a pointer to a C++ class’ member function. qsort can’t use this function, because in order to call circ_sort::Compare(), qsort would need the class’ this pointer.

You can make circ_sort::Compare() a static member function and qsort should be happy although you may not be able to implement the functionality that you want with a static function.

Let me know if any of this doesn’t make sense and I will explain further. But I don’t want to explain stuff you might already know. Feel free to PM me as well. I’ll be up for a little bit longer.

The comparator argument to qsort expects a pointer to a function that takes two (const) void pointers. You’ve passed qsort a pointer to a non-static class method. Methods take, along with their explicit arguments, an initial implicit argument which is the object’s “this” pointer. That’s why the error message shows a “circ_sort::” decoration on the function type: the method’s arguments are really something like (circ_sort&, void*, void*).

If your comparator doesn’t actually use any member data, you can make it static. If it does use member data, you can use a member-function adaptor similar to the ones in <functional> to convert this member function into a real function.

This is how you would make it static. A static member function cannot access any of the class’ variables though (e.g. size, nextEntryLocation, circBuffer, sortedBuffer). That is likely ok for your case below.


#include <cstdio>
#include <cstdlib>

using namespace std;

class circ_sort
{
   public:
      static int Compare( const void* a, const void* b );
      void QSort( void );

   private:
      int         size,
                  nextEntryLocation;
      double   *  circBuffer,
               ** sortedBuffer;
};

/*static*/ int circ_sort::Compare (const void * a, const void * b)
{
   return 0;
}

void circ_sort::QSort( void )
{
   qsort( sortedBuffer, (size_t) size, sizeof( double* ), Compare );
}

int main( void )
{
   return 0;
}

Under the hood, circ_sort is (more or less) just a struct. If you were to write your code in C, it would look like this:


struct circ_sort
{
      int (*Compare)( circ_sort* this, const void* a, const void* b );
      void (*QSort)( circ_sort* this );

      int         size,
                  nextEntryLocation;
      double   *  circBuffer,
               ** sortedBuffer;
};

int Compare( circ_sort* this, const void* a, const void* b )
{
}

void QSort( circ_sort* this ) {
   qsort( sortedBuffer, (size_t) size, sizeof( double* ), Compare );
}


Behind the scenes, the function pointers in circ_sort for Compare and QSort are set to the functions outside of the struct declaration. And of course C++ hides the first argument to all of the functions, which is a pointer to the struct itself–which is how the function is able to access the variables in the object.

EDIT: Making the functions static means that instances of your object aren’t passed to them. All of the variables in your object would need to be static as well–but that means that you can’t have multiple versions of them. The better option is “friend” functions.

EDIT2: I might be wrong on the “friend” thing. It’s been a while. However, more likely the key issue is that you’re using C’s qsort instead of C++'s sort. You’re better off to look up what the C++ way is.

Thanks everyone for that. The code seems to work fine when Compare is static, but I went ahead and modified the code to use the C++ sort() function.