0

I have this templated member "function" which arguments are an object instance and a member function of this object (like a wrapper):

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

If we have this class:

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

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

The call to this function will be like this:

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

    return 0;
};

Now this is the question. If I want to call a thread which works over the member function "waitData", how should it be written?

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

    return 0;
};

Thanks in advance.

vicalomen
  • 1
  • 2
  • plz, if any of the answers answer your question well, consider upvoting and accepting it. if not plz, specify the cause. – asmmo Mar 12 '21 at 14:18
  • Does this answer your question? [std thread call template member function of template class: compiler error](https://stackoverflow.com/questions/21617860/std-thread-call-template-member-function-of-template-class-compiler-error) – bers Aug 16 '22 at 10:29

2 Answers2

1

You may wrap it in a lambda:

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

Of course, need to think about object lifetime - in this example all 3 objects are captured by reference, which means they need to be kept around while the thread is running.

rustyx
  • 80,671
  • 25
  • 200
  • 267
1

You can wrap it in a lambda as the previous answer suggest or you can use the following method.

Note that you may use the value semantic instead of reference one because there are no fields in any class. But I will use your way.

#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
    };
};
asmmo
  • 6,922
  • 1
  • 11
  • 25
  • Why this only works with "std::ref(object)" instead of "&object"? – vicalomen Mar 13 '21 at 19:37
  • @vicalomen because `std;;thread` takes values not reference and `std::ref()` makes a [reference wrapper](https://en.cppreference.com/w/cpp/utility/functional/reference_wrapper) then it taken by value bu on using it, it gives the real reference. – asmmo Mar 15 '21 at 04:44