【问题标题】:Passing reference to object in callback function to std::thread [duplicate]将回调函数中对象的引用传递给 std::thread [重复]
【发布时间】:2018-07-01 10:56:15
【问题描述】:

我正在尝试做这样的事情:

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

当我尝试构建它时,出现了一些错误:

在 /usr/include/c++/6/thread:39:0 包含的文件中, 来自 src/rpi_server/rpiserver.cpp:11: /usr/include/c++/6/functional:在“struct std::_Bind_simple”的实例化中: /usr/include/c++/6/thread:138:26: 来自‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (*&)(int, RPiServer&); _Args = {int&, RPiServer&}]’ src/rpi_server/rpiserver.cpp:89:79:从这里需要 /usr/include/c++/6/functional:1365:61: 错误:在‘class std::result_of’中没有名为‘type’的类型 typedef typename result_of<_callable>::type result_type; ^~~~~~~~~~~ /usr/include/c++/6/functional:1386:9: 错误:‘class std::result_of’中没有名为‘type’的类型 _M_invoke(_Index_tuple<_indices...>) ^~~~~~~~~ Makefile:29: 目标“build/rpi_server/rpiserver.o”的配方失败

当我以以下方式更改线程函数时(删除对对象的引用):

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

一切都构建得非常好。当我将引用作为参数传递给线程函数时,我做错了什么?

【问题讨论】:

    标签: c++ multithreading c++11 pthreads stdthread


    【解决方案1】:

    所以这里有一个工作示例:

    #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 错误。

    【讨论】:

    • 编译器将 template&lt; class Function, class... Args &gt; explicit thread( Function&amp;&amp; f, Args&amp;&amp;... args ) 构造函数的参数推导出为 void(*)(int,RPiServer&amp;),int,RPiServer),这将不起作用,因为您无法将 RPiServer 值绑定到非 const 左值引用。您不能将模板参数传递给构造函数,因此您需要在*this 上显式指定std::ref。或者,使 RPiServer&amp; 参数 const 也可以编译,但您可能会创建一个临时的。
    猜你喜欢
    • 2017-03-22
    • 1970-01-01
    • 2012-09-12
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 2019-01-13
    • 2014-01-29
    • 2020-12-15
    相关资源
    最近更新 更多