使用类构造函数在线程中启动成员函数

Posted

技术标签:

【中文标题】使用类构造函数在线程中启动成员函数【英文标题】:Starting a member function in a thread using class constructor 【发布时间】:2015-06-22 06:44:49 【问题描述】:

我有一个包含一个成员函数的类,我想将它传递给std::thread 的构造函数。

#include <thread>
#include <iostream>

struct StatsClientImpl

    std::thread t;
    size_t q_len;

    StatsClientImpl() : q_len(0)
    
        t = std::thread(&StatsClientImpl::de_q, this);
    

    ~StatsClientImpl()
    
        if (t.joinable())
            t.join();
    

    void de_q()
    
        std::cout << "in de_q\n";
    
;

int main()

    StatsClientImpl s;

我收到以下错误:

/Users/apple/platform/stats-client/src/main/cpp/StatsClientImpl.cpp:21:17: error: no matching constructor for initialization of 'std::thread'
    std::thread te(&StatsClientImpl::de_q, this);
                ^  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:374:9: note: candidate constructor template not viable: requires single argument '__f', but 2 arguments were provided
thread::thread(_Fp __f)
        ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:263:5: note: candidate constructor not viable: requires 1 argument, but 2 were provided
    thread(const thread&);
    ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:270:5: note: candidate constructor not viable: requires 0 arguments, but 2 were provided
    thread() _NOEXCEPT : __t_(0) 

【问题讨论】:

奇怪;我搜索了'std::thread member function'并找到了答案:***.com/questions/10673585/… 我知道。我也看到了。 所以它是相同的代码,只是没有静态包装器。提示:移除静态包装器。 Passing member functions to std::thread的可能重复 我看不出你的代码有什么问题。正如其他人所提到的,不需要通过static 函数传递this 指针。如果您仍然遇到错误,请发帖SSCCE 【参考方案1】:

C++11 线程允许直接调用非静态方法。您使用的语法是为此而设计的,只需将 de_q_caller 替换为 de_q:

t = std::thread(&StatsClientImpl::de_q, this);

更新:因为您的编译器似乎不允许这样做,请尝试

t = std::thread(std::bind(&StatsClientImpl::de_q, this));

clang 编译器可能需要添加以下编译器选项:

-std=c++11

【讨论】:

这很奇怪。你能发布方法 de_q 的定义吗? 如果使用 std::bind 是否可以编译? t = std::thread(std::bind(&StatsClientImpl::de_q, this)); 没试过。你能告诉我怎么做吗? 它给了我一个错误:'C++/ObjC++' 不允许使用无效参数'-std=c11' 糟糕,选项应该是 -std=c++11 。你试过 std::bind 吗?

以上是关于使用类构造函数在线程中启动成员函数的主要内容,如果未能解决你的问题,请参考以下文章

使用成员函数启动线程

使用移动语义在构造函数中初始化类成员

在构造函数中调用类成员的构造函数

后续:执行一个类的成员函数

在单独的线程中使用参数启动成员函数

C++成员初始化列表(构造函数后加冒号:)(用于在构造函数中初始化类成员变量,可以避免使用构造函数体内的赋值语句,可以确保成员变量在对象构造之初就已经被正确初始化,提高代码的性能和可读性)