问题描述
我一般对std::thread
和C ++ 11不熟悉。尝试使用https://en.cppreference.com/w/cpp/thread/thread/thread中的示例进行模拟,我试图看看是否可以使用具有非空参数列表的类成员函数调用运算符生成std::thread
,如以下代码所示:
// main.cpp
#include <iostream>
#include <iostream>
#include <thread>
class Foo {
public:
void operator()( int& i ) {
std::cout << i << std::endl;
}
};
int main( int argc,char* argv[] ) {
Foo f;
int i = 42;
std::thread t1( f,i );
t1.join();
return 0;
}
错误消息是神秘的:
$ g++ --version && g++ ./main.cpp -lpthread && ./a.out
g++ (Debian 6.3.0-18+deb9u1) 6.3.0 20170516
copyright (C) 2016 Free Software Foundation,Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or fitness FOR A PARTIculaR PURPOSE.
In file included from /usr/include/c++/6/thread:39:0,from ./main.cpp:5:
/usr/include/c++/6/functional: In instantiation of ‘struct std::_Bind_simple<Foo(int)>’:
/usr/include/c++/6/thread:138:26: required from ‘std::thread::thread(_Callable&&,_Args&& ...) [with _Callable = Foo&; _Args = {int&}]’
./main.cpp:19:24: required from here
/usr/include/c++/6/functional:1365:61: error: no type named ‘type’ in ‘class std::result_of<Foo(int)>’
typedef typename result_of<_Callable(_Args...)>::type result_type;
^~~~~~~~~~~
/usr/include/c++/6/functional:1386:9: error: no type named ‘type’ in ‘class std::result_of<Foo(int)>’
_M_invoke(_Index_tuple<_Indices...>)
相反,空的参数列表调用运算符可以正常工作:
// main.cpp
#include <iostream>
#include <iostream>
#include <thread>
class Foo {
public:
void operator()() {
std::cout << 42 << std::endl;
}
};
int main( int argc,char* argv[] ) {
Foo f;
int i = 42;
std::thread t1( f );
t1.join();
return 0;
}
$ g++ --version && g++ ./main.cpp -lpthread && ./a.out
g++ (Debian 6.3.0-18+deb9u1) 6.3.0 20170516
copyright (C) 2016 Free Software Foundation,Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or fitness FOR A PARTIculaR PURPOSE.
42
我的第一次尝试是否完全可行-我是否只有语法错误?有没有办法使用对象及其非空参数列表调用运算符来生成std :: thread?
我相信这个问题与Start thread with member function不同,因为这个问题专门涉及使用成员对象 call运算符生成线程。我知道这可以通过lambdas完成。 / p>
解决方法
除非您明确表示,否则
std::thread
不允许您通过引用传递,因为它很容易引起生命周期问题。使用std::ref
来明确表示您通过引用传递了i
:
std::thread t1( f,std::ref(i) );
或者,按值传递。在通过引用将某些内容传递给线程之前,请认真考虑并确保有必要。您传递的变量必须超过其在线程中的使用范围。