将回调函数中的对象引用传递给 std::thread
Passing reference to object in callback function to std::thread
我正在尝试做这样的事情:
void commands_conn_handler(int socket, RPiServer& server) {
// Not important code about handling connection
}
class RPiServer {
public:
void Accept(void Accept(void (*acceped_conn_handler)(int, RPiServer&)) {
// (...)
int remote_socket = 0; // Doesn't matter - example.
std::thread conn_handler_thread(acceped_conn_handler, remote_socket, *this);
conn_handler_thread.join();
}
};
int main() {
RPiServer commands_server();
commands_server.Accept(commands_conn_handler);
}
当我尝试构建它时,出现了一些错误:
In file included from /usr/include/c++/6/thread:39:0,
from src/rpi_server/rpiserver.cpp:11:
/usr/include/c++/6/functional: In instantiation of ‘struct std::_Bind_simple’:
/usr/include/c++/6/thread:138:26: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (*&)(int, RPiServer&); _Args = {int&, RPiServer&}]’
src/rpi_server/rpiserver.cpp:89:79: required from here
/usr/include/c++/6/functional:1365:61: error: no type named ‘type’ in ‘class std::result_of’
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’
_M_invoke(_Index_tuple<_Indices...>)
^~~~~~~~~
Makefile:29: recipe for target 'build/rpi_server/rpiserver.o' failed
当我按以下方式更改线程函数时(删除对对象的引用):
void commands_conn_handler(int socket) {
// Not important code about handling connection
}
class RPiServer {
public:
void Accept(void (*acceped_conn_handler)(int)) {
// (...)
int remote_socket = 0; // Doesn't matter - example.
std::thread conn_handler_thread(acceped_conn_handler, remote_socket);
conn_handler_thread.join();
}
};
int main() {
RPiServer commands_server();
commands_server.Accept(commands_conn_handler);
}
一切都构建得很好。当我将引用作为参数传递给线程函数时我做错了什么?
所以这里有一个工作示例:
#include <thread>
#include <functional>
class RPiServer;
void commands_conn_handler(int socket, RPiServer &server) {
// Not important code about handling connection
}
class RPiServer {
public:
void Accept(void (*acceped_conn_handler)(int, RPiServer&)) {
// (...)
int remote_socket = 0; // Doesn't matter - example.
std::thread conn_handler_thread(acceped_conn_handler, remote_socket, std::ref(*this));
conn_handler_thread.join();
}
};
int main() {
RPiServer commands_server;
commands_server.Accept(commands_conn_handler);
}
您遇到的错误是因为您没有为 conn_handler_thread
的构造函数提供正确的类型。要显式获取对对象的引用(您需要在此处执行此操作),请使用 std::ref()
函数。
P.S.: 此外,您复制粘贴了错误的代码示例,复制了 void Accept
部分。您在 main()
中也有 most vexing parse 错误。
我正在尝试做这样的事情:
void commands_conn_handler(int socket, RPiServer& server) {
// Not important code about handling connection
}
class RPiServer {
public:
void Accept(void Accept(void (*acceped_conn_handler)(int, RPiServer&)) {
// (...)
int remote_socket = 0; // Doesn't matter - example.
std::thread conn_handler_thread(acceped_conn_handler, remote_socket, *this);
conn_handler_thread.join();
}
};
int main() {
RPiServer commands_server();
commands_server.Accept(commands_conn_handler);
}
当我尝试构建它时,出现了一些错误:
In file included from /usr/include/c++/6/thread:39:0, from src/rpi_server/rpiserver.cpp:11: /usr/include/c++/6/functional: In instantiation of ‘struct std::_Bind_simple’: /usr/include/c++/6/thread:138:26: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (*&)(int, RPiServer&); _Args = {int&, RPiServer&}]’ src/rpi_server/rpiserver.cpp:89:79: required from here /usr/include/c++/6/functional:1365:61: error: no type named ‘type’ in ‘class std::result_of’ 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’ _M_invoke(_Index_tuple<_Indices...>) ^~~~~~~~~ Makefile:29: recipe for target 'build/rpi_server/rpiserver.o' failed
当我按以下方式更改线程函数时(删除对对象的引用):
void commands_conn_handler(int socket) {
// Not important code about handling connection
}
class RPiServer {
public:
void Accept(void (*acceped_conn_handler)(int)) {
// (...)
int remote_socket = 0; // Doesn't matter - example.
std::thread conn_handler_thread(acceped_conn_handler, remote_socket);
conn_handler_thread.join();
}
};
int main() {
RPiServer commands_server();
commands_server.Accept(commands_conn_handler);
}
一切都构建得很好。当我将引用作为参数传递给线程函数时我做错了什么?
所以这里有一个工作示例:
#include <thread>
#include <functional>
class RPiServer;
void commands_conn_handler(int socket, RPiServer &server) {
// Not important code about handling connection
}
class RPiServer {
public:
void Accept(void (*acceped_conn_handler)(int, RPiServer&)) {
// (...)
int remote_socket = 0; // Doesn't matter - example.
std::thread conn_handler_thread(acceped_conn_handler, remote_socket, std::ref(*this));
conn_handler_thread.join();
}
};
int main() {
RPiServer commands_server;
commands_server.Accept(commands_conn_handler);
}
您遇到的错误是因为您没有为 conn_handler_thread
的构造函数提供正确的类型。要显式获取对对象的引用(您需要在此处执行此操作),请使用 std::ref()
函数。
P.S.: 此外,您复制粘贴了错误的代码示例,复制了 void Accept
部分。您在 main()
中也有 most vexing parse 错误。