[英]compile error only when passing capture var in labda to pthread_create
在下面的代码中,我让pthread_create使用lambdas调用类函数(可以使用函数指针完成相同的操作)。 前两个编译正常,但第三个给出了编译错误,看起来像是试图将指向类成员的指针转换为C类型的函数。 不确定。
#include <pthread.h>
class threadtest
{
private:
void* thread1() { return nullptr; }
void* thread2( void* p ) { return p; }
public:
void start();
};
void threadtest::start()
{
pthread_t thd0;
auto fn0 = []( void* a_pArg ) -> void* { return static_cast<threadtest*>( a_pArg )->thread1(); };
pthread_create( &thd0, NULL, fn0, (void*)this );
pthread_t thd1;
auto fn1 = []( void* a_pArg ) -> void* { void* p = nullptr; return static_cast<threadtest*>( a_pArg )->thread2( p ); };
pthread_create( &thd1, NULL, fn1, (void*)this );
pthread_t thd2;
void* p;
auto fn3 = [p]( void* a_pArg ) -> void* { return static_cast<threadtest*>( a_pArg )->thread2( p ); };
pthread_create( &thd2, NULL, fn3, (void*)this );
}
这是错误:
threadtest.cpp: In member function ‘void threadtest::start()’:
threadtest.cpp:31:50: error: cannot convert ‘threadtest::start()::__lambda2’ to ‘void* (*)(void*)’ for argument ‘3’ to
‘int pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*)’
pthread_create( &thd2, NULL, fn3, (void*)this );
编译器版本为:gcc(Ubuntu 4.8.2-19ubuntu1)4.8.2
在我的实际代码中,我没有做第二个或第三个示例。 我知道线程访问它时,从堆栈中退出的var上存在竞争条件。 我只是好奇为什么在捕获任何变量时编译器会引发错误? 有什么变化?
谢谢
您的名为fn3
lambda表达式捕获变量p
。 仅无捕获的lambda定义对函数指针的转换。
引用N3337,第5.1.2 / 6节 [expr.prim.lambda]
没有lambda捕获的lambda表达式的闭包类型具有指向该函数的指针的公共非虚拟非显式const转换函数,该函数具有与闭包类型的函数调用运算符相同的参数和返回类型。 该转换函数返回的值应是一个函数的地址,该函数在被调用时与调用闭包类型的函数调用操作符具有相同的作用。
因此,当您尝试在调用pthread_create
时将lambda转换为函数指针时,它会失败。
不允许这样做的原因是,函数指针无法携带lambda捕获的状态。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.