Search code examples
c++

How to call C++ member function from template function?


I'm having a problem passing a class as a shared_ptr into this run function so that I can thread it in the background.

class myA {
    public:
        MyA() = default;

        void func(int) { ... };
};

class myB {
    public:
        MyB() = default;

        void func2(int) { ... };
};

auto myA = std::make_shared_ptr<MyA>();
auto myB = std::make_shared_ptr<MyB>();

run(myA, &myA::func, 1, 5);
run(myB, &myB::func2, 1, 3);
        

The problem is, I'm not sure how to call the function that takes an int as a parameter.

template <typename C, typename F>
void run(std::shared_ptr<C> c, F f, int a, int b)
{
    std::thread([&c, &f, a, b]() {
        while (true) {
            // I know this is wrong, but how to call the 
            // functions passed in (F).
            c.f(a);

            std::this_thread::sleep_for(std::chrono::seconds(b));
        }
    }).detach();
}

Can anyone help out w/ how to do this properly?


Solution

  • You can use std::invoke which has been built to handle any type of function call. That would give you

    template <typename C, typename F>
    void run(std::shared_ptr<C> c, F f, int a, int b)
    {
        std::thread([c, f, a, b]() { // dont take references if the thread will outlive the function arguments
            while (true) {
                std:invoke(f, *c, a); // member functions take the object as an implicit first parameter.
    
                std::this_thread::sleep_for(std::chrono::seconds(b));
            }
        }).detach();
    }