简体   繁体   中英

error: argument of type ‘void* (Thread::)(void*)’ does not match ‘void* (*)(void*)’

I'm doing to implement thread class for my own using pthread . So, I create Thread class as below :

class Thread
{
public:
  Thread()
  {
  }

  virtual void* run(void *params) = 0;

  void start(void *params)
  {
    pthread_create (&threadId, 0, run, params);
    pthread_join (threadId, 0);
  }

private:
  pthread_t threadId;
};

After implementing this class and override virtual run function, I do compile this project. But error: argument of type 'void* (Thread::)(void*)' does not match 'void* (*)(void*)' occurs. What is wrong in my code?

Thanks in advance :)

Exactly what the compiler is telling you.

pthread_create is expecting a function with the signature :

void* (*)(void*)

Which is a function pointer.

However, you are providing something with this signature:

void* (Thread::)(void*)

Which is not a function pointer, but a pointer to member function. There is a difference : a pointer to member function needs an instance of an object in order to work properly (here, it would need an instance of Thread).

A usual solution would be to make your function run static : it would not be a member function anymore - it doesn't NEED an instance of Thread in order to work properly anymore, and you could pass your current instance as the last parameter of pthread_create in order to act on it once the thread is launched. You would just need to save the parameters in the class itself.

public:
 void start(void *params)
 {
  this->my_thread_params = params;
  pthread_create (&threadId, 0, run, static_cast<void*>(this));
 }

private:
  static void *run(void *my_object)
  {
    // here, my_object already contains the params you passed to the function start
    static_cast<Thread*>(my_object)->my_member_function();
  }

The error message is telling you that a pointer to a member function in Thread that takes and returns a void* ( void* (Thread::*)(void*) ) is not convertible to a pointer to function taking and returning the same void* .

While the declaration of the member function may look similar to the type that you need, there is an implicit this pointer of type Thread that needs to be injected on any call to Thread::run

pthread_create is a C function, and knows nothing of C++ member functions. You'll need to give it a static or non-member function, and pass a pointer to your Thread object via the final argument of pthread_create ; something like:

class Thread
{
    virtual void* run(void *params) = 0;

    void start(void * params)
    {
        this->params = params;
        pthread_create(&threadId, 0, &Thread::static_run, this);
    }

    static void * static_run(void * void_this)
    {
         Thread * thread_this = static_cast<Thread*>(void_this);
         return thread_this->run(thread_this->params);
    }

private:
    pthread_t threadId;
    void *params;
};

Of course in modern C++, this is rather more straightforward:

std::thread thread;

void start(void * params)
{
    thread = std::thread([this]{run(params);});
}

(Although of course you shouldn't be using void* to pass your parameters, and there's probably no good reason to wrap the thread up in a class in the first place.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM