3
votes

code:

    // create class instance  
    MC_THREAD MTHR;  
    // set some values in the class  
    MTHR.setup_mc_thread("com6", &es);  
    // create an thread to run the non-static member function   
    std::thread MCTHR(MC_THREAD::start_mc_thread, std::ref(MTHR)); 

the definition of the function is:

    void MC_THREAD::start_mc_thread(){ 
        while(1){
            //do_stuff
        }
    } 

The above code compiles (and works correctly) on windows 8 & 10 using TDM-GCC compiler based on gcc 5.1.0.

The above code generates the following error with gcc 7.3.1 on linux:
error: invalid use of non-static member function ‘void MC_THREAD::start_mc_thread()’|

The machine which generates the error is running fedora 27 using gcc (GCC) 7.3.1 20180303 (Red Hat 7.3.1-5)

Any suggestions would be appreciated!

Solved: See Sam's Comment Below

Also had to link pthread.

1
Using std::thread to execute a class method requires the first parameter to be a plain pointer, i.e. this, and not a reference. Change the parameter to simply &MTHR. - Sam Varshavchik
@sam Please write that as an answer. - Tripp Kinetics
@TrippKinetics -- it's not the right answer. - Pete Becker

1 Answers

0
votes

I initially thought the problem to be the usage of std::reference_wrapper. But the compilation error is actually due to the class member function needing to be a pointer. The following compiles with gcc 7.3.1:

#include <thread>
#include <utility>
#include <functional>

class x {
public:

    void start_thread();
};

int main()
{
    x y;

    std::thread thr{&x::start_thread, std::ref(y)};
}

The usual approach to launching a thread for a class member is to pass a plain pointer as the class instance. This works too, in this case:

std::thread thr{&x::start_thread, &y};

And this is the more common syntax. The reference wrapper is not really needed. But in all cases the first parameter must be a pointer to a class method. &x::start_thread is such a pointer. x::start_thread itself isn't. That's the real problem.

The parameter to std::thread's constructor is specified merely as...

f - Callable object to execute in the new thread

You have to really dig into the definition of a callable object. The basic usage that I had in mind corresponds to the third option listed there for a callable object. But a reference wrapper is also acceptable. However, in all cases you have to have a pointer to a member function as the first argument.