在模板化成员函数上创建线程

问题描述

我有这个模板化成员“函数”,它的参数是对象实例和该对象的成员函数(如包装器):

class Monitor
{
    Monitor();
    ~Monitor();
    
    template <typename O,typename F>
    void (O object,F function)
    {
        object.function();
    }
}

如果我们有这个类:

class Object
{
     Object();
     ~Object();

     function()
     {
          std::cout << "Do something" << std::endl;
     };
}

对这个函数调用将是这样的:

int main()
{
    Monitor monitor;
    Object object;
    
    monitor.waitData(object,function);

    return 0;
};

现在问题来了。如果我想调用一个作用于成员函数“waitData”的线程,应该怎么写?

int main()
{
    Monitor monitor;
    Object object;
    
    // std::thread threadWait(monitor.waitData(object,function)) -> ObvIoUsly gets an error
    std::thread threadWait(???????);

    return 0;
};

提前致谢。

解决方法

您可以将其包装在 lambda 中:

std::thread threadWait([&]{
    monitor.waitData(object,function);
});

当然,需要考虑对象的生命周期——在这个例子中,所有 3 个对象都是通过引用捕获的,这意味着它们需要在线程运行时保留。

,

您可以按照上一个答案的建议将其包装在 lambda 中,也可以使用以下方法。

请注意,您可以使用值语义而不是引用语义,因为任何类中都没有字段。但我会用你的方式。

#include <iostream>
#include <thread>

struct Monitor{
    template <typename O,typename F>
    void waitData(O& object,F function){
        object.function();
    }
};

struct Object{
    void function(){
        std::cout << "Do something" << std::endl;
    };
};

int main()
{
    Monitor monitor;
    Object object;
    auto t = std::jthread{
            &Monitor::waitData<Object,void(Object::*)(void)/*decltype(&Object::function)*/>,std::ref(monitor),std::ref(object),&Object::function
    };
};