Passing any class member function with any number of arguments to a function outside the class

只愿长相守 提交于 2021-01-07 01:30:47

问题


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

}

回答1:


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.

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.



来源:https://stackoverflow.com/questions/65347599/passing-any-class-member-function-with-any-number-of-arguments-to-a-function-out

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!