将具有任意数量参数的任何类成员函数传递给类外的函数 [英] Passing any class member function with any number of arguments to a function outside the class

查看:34
本文介绍了将具有任意数量参数的任何类成员函数传递给类外的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Remy 发布了一个很好的解决方案,可以将具有任意数量参数的任何函数传递给 std::线程这里.我想知道它如何用于类成员函数.

Remy posted a great solution to pass any function with any number of arguments to std::thread, here. I was wondering how it could be used for class member functions.

#include <iostream>
#include <thread>
#include <mutex>

#define __PRETTY_FUNCTION__ __FUNCSIG__

std::mutex my_mutex;

template<class Function, class... Args>
void runFunctionInThread(Function f, Args&&... args) {
    // Beside starting a thread, this function performs other 
    // task using the function and its arguments.
    std::thread t(f, std::forward<Args>(args)...);
    t.detach();
}

class MyClass
{
public:
    MyClass() {};

    void myFunc1() { std::unique_lock<std::mutex> lock(my_mutex); std::cout << __PRETTY_FUNCTION__ << "\n"; }
    void myFunc2(int value) { std::unique_lock<std::mutex> lock(my_mutex); std::cout << __PRETTY_FUNCTION__ << "value is " << value << "\n"; }
    void myFunc3(int value1, int value2) { std::unique_lock<std::mutex> lock(my_mutex); std::cout << __PRETTY_FUNCTION__ << "value1+value2 is " << value1 + value2 << "\n"; }

    void manager() {
        void (MyClass::*f1)() = &MyClass::myFunc1;
        void (MyClass::*f2)(int) = &MyClass::myFunc2;
        void (MyClass::*f3)(int,int) = &MyClass::myFunc3;

        runFunctionInThread(f1);
        runFunctionInThread(f2, 2);
        runFunctionInThread(f3, 3, 3);
    }

};

void isolatedFunc1() { std::unique_lock<std::mutex> lock(my_mutex); std::cout << __PRETTY_FUNCTION__ << "\n"; }
void isolatedFunc2(int value) { std::unique_lock<std::mutex> lock(my_mutex); std::cout << __PRETTY_FUNCTION__ << " value is " << value << "\n"; }
void isolatedFunc3(int value1, int value2) { std::unique_lock<std::mutex> lock(my_mutex); std::cout << __PRETTY_FUNCTION__ << " value1+value2 is " << value1 + value2 << "\n"; }

int main()
{
    runFunctionInThread(&isolatedFunc1); // Works flawlessly
    runFunctionInThread(&isolatedFunc2, 2); // Works flawlessly
    runFunctionInThread(&isolatedFunc3, 3, 3); // Works flawlessly

    MyClass m;
    m.manager();

}

推荐答案

如果你想调用一个成员函数,你也需要将对象传递给 std::thread:

If you want to call a member function you'll need to pass the object to std::thread too:

void manager() {
    //...
    runFunctionInThread(f1, this);
    runFunctionInThread(f2, this, 2);
    runFunctionInThread(f3, this, 3, 3);
}

注意:我注意到你分离了你的线程.然后,您需要手动确保它们在您的程序执行之前已经结束,否则如果它们仍在运行,您会在程序退出时感到意外.

Note: I noticed that you detach your threads. You then need to manually make sure that they have ended before your program does or you are in for surprises at program exit if they are still running.

将正在运行的线程保存在容器中通常更容易(例如 std::list),然后 join() 将它们保存在容器中.在 C++20 中,您甚至可以将其设为 std::list<std::jthread> 使它们在容器销毁时自动加入.

It's often easier to keep the running threads in a container (like a std::list<std::thread>) and join() them later. In C++20 you could even make it std::list<std::jthread> to have them automatically joined when the container is destroyed.

这篇关于将具有任意数量参数的任何类成员函数传递给类外的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆