1

I'm recently using C++11 threads and I have a question about something (strange for me) happened. I created a method inside a class, able to start thread. The starting thread method and the callback function of the thread are class methods. To clarify, in my Person.cpp file I have:

void Person::callbackForThread(){
    ...
}


void Person::startThread(){
    this call threads. Something like:
    thread(callbackForThread);
}

The problem is that C++11 doesn't allow me to declare these two function as class methods. This means that if I declare them as normal function, i.e:

 void callbackForThread(){
    ...
}


void startThread(){
    this call threads. Something like:
    thread(callbackForThread);
}

Everythings works. I would know how could I declare thread and callback inside a class in C++, if it is possible. For the farther, I have omitted the inclusion of the libraries and the name of the real class. The class shown in this question is fictitious.

BossShell
  • 379
  • 3
  • 14

1 Answers1

2

This is because Person::callbackForThread takes an hidden first argument: this.

This is where lambdas and std::bind come in handy:

thread([this]() { this->callbackForThread(); });

or

using namespace std::placeholders;
thread(std::bind(&Person::callbackForThread, this, _1));

From krzaq feedback: if thread is std::thread, it needs to be detached or saved somehow.

YSC
  • 38,212
  • 9
  • 96
  • 149
  • 5
    or just `thread(&Person::callbackForThread, this)`, no need for bind – PeterT Nov 29 '17 at 10:27
  • Yes, It sound great. You make my day! Thank you – BossShell Nov 29 '17 at 10:30
  • 1
    Why not just `thread(&Person::callbackForThread, this)`? As a side note, this is an expression and it will destroy the thread object at the end of it. If it has not finished by that time (very unlikely), you'll call `std::terminate`. – krzaq Nov 29 '17 at 10:31
  • @PeterT I'd rather not: 1/ this is true only if we're talking about `std::thread` and not some user-defined `thread` thing. 2/ the use of `std::bind` is idiomatic and well understood by C++ developers. (but yeah, ok, why not) – YSC Nov 29 '17 at 10:31
  • Why can I write thread(myCallBackFun), so without the &, if myCallBackFun is a normal function and thread(&Person::myCallBackFun) if myCallBackFun is a class method? I mean, I understand the Person:: prefix but not the &. Is not implicit that I'm using the reference? as in the first case? – BossShell Nov 29 '17 at 10:46
  • 1
    @BossShell you're taking the adress of a function, the unary `&` operator is expected. The thing is, for free functions, there is a special rule somewhere coming from the C language which allows to omit it. All Hail Compatibility! – YSC Nov 29 '17 at 11:49