Linux下C++线程调用非静态成员函数报错的非静态修复方法
解决非静态成员函数创建线程的错误问题
你碰到的这个invalid use of non-static member function错误,本质原因是非静态成员函数天生和对象绑定——它背后隐含了一个this指针参数,用来指向调用它的具体对象实例。而std::thread的构造函数没办法自动识别这个隐含的this,直接传函数名自然会报错。
不用把函数改成静态的话,有几种简单的修复方式:
传递当前对象的
this指针
因为f2是Sniffer的成员函数,在f2内部的this就指向当前的Sniffer对象。我们只需要把this作为第一个参数传给线程构造函数,同时明确指定成员函数的地址格式:void Sniffer::f2() { int y = 5; // 注意成员函数地址要写成 &类名::函数名 std::thread t1(&Sniffer::f1, this, y); t1.join(); }这样线程就知道要在当前对象上调用
f1了。用lambda表达式捕获
this
lambda可以直接捕获当前对象的this,然后在lambda体里调用成员函数,写法更直观灵活:void Sniffer::f2() { int y = 5; std::thread t1([this, y]() { f1(y); // 捕获this后可以直接调用成员函数 }); t1.join(); }这种方式尤其适合成员函数参数较多的场景,代码可读性更高。
用
std::bind绑定对象实例
可以通过std::bind把成员函数和this绑定成一个可调用对象,再传给线程:#include <functional> // 需要包含这个头文件 void Sniffer::f2() { int y = 5; std::thread t1(std::bind(&Sniffer::f1, this, y)); t1.join(); }不过这种写法现在不如lambda常用,lambda的语法更简洁。
另外还要补充一点:你的main函数里目前没有创建Sniffer的实例,所以代码根本不会执行到线程部分,记得补上:
int main() { Sniffer s; s.f2(); return 0; }
内容的提问来源于stack exchange,提问作者dakvamir
相关产品推荐
相关产品推荐

