错误:类型' void* (Thread::)(void*) '的参数与' void* (*)(void*) '

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

本文关键字:void 参数 Thread 错误 类型      更新时间:2023-10-16

我正在为自己使用pthread实现线程类。因此,我创建Thread类如下:

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

在实现了这个类并覆盖了virtual run函数之后,我编译了这个项目。但是出现了error: argument of type ‘void* (Thread::)(void*)’ does not match ‘void* (*)(void*)’。我的代码有什么问题?

提前感谢:)

就是编译器告诉你的。

pthread_create正在等待一个签名为:

的函数

void* (*)(void*)

是一个函数指针。

但是,您提供的内容具有以下签名:

void* (Thread::)(void*)

不是函数指针,而是指向成员函数的指针。不同之处在于:指向成员函数的指针需要一个对象的实例才能正常工作(这里需要一个Thread的实例)。

一个常见的解决方案是让你的函数run static:它不再是一个成员函数-它不再需要一个线程的实例来正常工作了,你可以传递你的当前实例作为pthread_create的最后一个参数,以便在线程启动后对它进行操作。您只需要将参数保存在类本身中。

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

pthread_create是一个C函数,对c++成员函数一无所知。你需要给它一个静态或非成员函数,并通过pthread_create的最后参数传递一个指向Thread对象的指针;比如:

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

当然,在现代c++中,这要简单得多:

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

(当然,您不应该使用void*来传递参数,而且可能没有很好的理由将线程包装在一个类中。)

这个错误信息告诉你,一个指向Thread中接受并返回void* (void* (Thread::*)(void*))的成员函数的指针不能转换为指向接受并返回相同void*的函数的指针。

虽然成员函数的声明可能看起来与您需要的类型相似,但在任何调用Thread::run

时都需要注入Thread类型的隐式this指针。