简体   繁体   English

仅当将Labda中的capture var传递给pthread_create时才编译错误

[英]compile error only when passing capture var in labda to pthread_create

In the code below, I am having pthread_create call a class function using lambdas (same can be done with a function pointer). 在下面的代码中,我让pthread_create使用lambdas调用类函数(可以使用函数指针完成相同的操作)。 The first two compile ok, but the third gives a compile error that looks like trying to convert a pointer to a class member to a C-type function. 前两个编译正常,但第三个给出了编译错误,看起来像是试图将指向类成员的指针转换为C类型的函数。 Not sure. 不确定。

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

Here is the error: 这是错误:

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

The compiler version is: gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2 编译器版本为:gcc(Ubuntu 4.8.2-19ubuntu1)4.8.2

In my actual code I am not doing the second or 3rd example. 在我的实际代码中,我没有做第二个或第三个示例。 I know there is a race condition on the var coming off of the stack while the thread gets access to it. 我知道线程访问它时,从堆栈中退出的var上存在竞争条件。 I am just curious as to why the compiler throws an error when any var gets captured? 我只是好奇为什么在捕获任何变量时编译器会引发错误? What changes? 有什么变化?

Thanks 谢谢

Your lambda expression named fn3 captures the variable p . 您的名为fn3 lambda表达式捕获变量p Only capture-less lambdas define a conversion to a function pointer. 仅无捕获的lambda定义对函数指针的转换。

Quoting N3337, §5.1.2/6 [expr.prim.lambda] 引用N3337,第5.1.2 / 6节 [expr.prim.lambda]

The closure type for a lambda-expression with no lambda-capture has a public non-virtual non-explicit const conversion function to pointer to function having the same parameter and return types as the closure type's function call operator. 没有lambda捕获lambda表达式的闭包类型具有指向该函数的指针的公共非虚拟非显式const转换函数,该函数具有与闭包类型的函数调用运算符相同的参数和返回类型。 The value returned by this conversion function shall be the address of a function that, when invoked, has the same effect as invoking the closure type's function call operator. 该转换函数返回的值应是一个函数的地址,该函数在被调用时与调用闭包类型的函数调用操作符具有相同的作用。

Hence, when you attempt to convert the lambda into a function pointer in the call to pthread_create it fails. 因此,当您尝试在调用pthread_create时将lambda转换为函数指针时,它会失败。


The reason this is disallowed is that there is no way for a function pointer to carry along the state that has been captured by the lambda. 不允许这样做的原因是,函数指针无法携带lambda捕获的状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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