在C++中,std::thread如何在不创建对象的情况下调用成员函数?

Sad*_*egg 2 c++ multithreading

如果我们有一个类H有一些operator()重载。如何从这些成员函数创建线程而不用实例化类中的对象H。考虑下面的代码

#include<iostream>
#include<thread>

class H {
    public:
        void operator()(){
            printf("This is H(), I take no argument\n");
        }

        void operator()(int x){
            printf("This is H(), I received %d \n",x);
        }

};

int main(){

    int param = 0xD;

    //No object created
    std::thread td_1 = std::thread(H());
    std::thread td_2 = std::thread(H(),param);

    td_1.join();
    td_2.join();

    //From an object
    H h;
    std::thread td_3 = std::thread(h);
    std::thread td_4 = std::thread(h,param);

    td_3.join();
    td_4.join();

    return 0;
}

Run Code Online (Sandbox Code Playgroud)

产生输出:

#include<iostream>
#include<thread>

class H {
    public:
        void operator()(){
            printf("This is H(), I take no argument\n");
        }

        void operator()(int x){
            printf("This is H(), I received %d \n",x);
        }

};

int main(){

    int param = 0xD;

    //No object created
    std::thread td_1 = std::thread(H());
    std::thread td_2 = std::thread(H(),param);

    td_1.join();
    td_2.join();

    //From an object
    H h;
    std::thread td_3 = std::thread(h);
    std::thread td_4 = std::thread(h,param);

    td_3.join();
    td_4.join();

    return 0;
}

Run Code Online (Sandbox Code Playgroud)

问题是,td_1和td_2如何在没有class对象的情况下调用operator()class的成员函数?HH

use*_*570 6

td_1和td_2如何在没有H类对象的情况下调用H类的成员函数operator()?

td_1td_2创建类型为 的对象H。这些对象是临时的。接下来,那些提供的函数对象(在本例中是临时对象)被移动/复制到属于新创建的执行线程的存储中,并从那里调用。

您可以通过添加默认构造函数并将构造函数移动到类内来确认这一点H,如下所示:

#include<iostream>
#include<thread>

class H {
    public:
        void operator()(){
            printf("This is H(), I take no argument\n");
        }

        void operator()(int x){
            printf("This is H(), I received %d \n",x);
        }
        //default constructor
        H()
        {
            std::cout<<"default constructor called"<<std::endl;
        }
        //move constructor 
        H(H&&)
        {
            std::cout<<"move constructor called"<<std::endl;
        }

};

int main(){

    int param = 0xD;

    std::thread td_1 = std::thread(H());
    std::thread td_2 = std::thread(H(),param);

    td_1.join();
    td_2.join();

 
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

上述程序的输出是

default constructor called
move constructor called
move constructor called
default constructor called
move constructor called
move constructor called
This is H(), I take no argument
This is H(), I received 13 
Run Code Online (Sandbox Code Playgroud)

  • @Sadegg对于您的其他问题,请查看[为什么在将临时变量传递给线程函数时移动构造函数被调用两次?](/sf/ask/3525399461/ Called-twice-当将临时对象传递给线程函数时)。您还可以提出一个单独的问题,如果上面提供的链接没有该问题的任何可接受的答案,为什么移动构造函数会调用两次。 (2认同)