Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ 11 Thread initialization with member functions compiling error [duplicate]

I'm just starting to use C++ 11 threads and I've been struggling on a (probably silly) error. This is my example program:

#include <iostream>
#include <thread>
#include <future>
using namespace std;

class A {
public:
  A() {
    cout << "A constructor\n";
  }

  void foo() {
    cout << "I'm foo() and I greet you.\n";
  }

  static void foo2() {
    cout << "I'm foo2() and I am static!\n";
  }

  void operator()() {
    cout << "I'm the operator(). Hi there!\n";
  }
};

void hello1() {
  cout << "Hello from outside class A\n";
}

int main() {
  A obj;
  thread t1(hello1); //  it works
  thread t2(A::foo2); // it works
  thread t3(obj.foo); // error
  thread t4(obj);     // it works

  t1.join();
  t2.join();
  t3.join();
  t4.join();
  return 0;
}

Is it possible to start a thread from a pure member function? If it is not, how can I wrap my foo function from object obj to be able to create such thread? Thanks in advance!

This is the compiling error:

thread_test.cpp: In function ‘int main()’: thread_test.cpp:32:22: error: no matching function for call to ‘std::thread::thread()’

thread_test.cpp:32:22: note: candidates are:

/usr/include/c++/4.6/thread:133:7: note: std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (A::*)(), _Args = {}]

/usr/include/c++/4.6/thread:133:7: note: no known conversion for argument 1 from ‘’ to ‘void (A::*&&)()’

/usr/include/c++/4.6/thread:128:5: note: std::thread::thread(std::thread&&)

/usr/include/c++/4.6/thread:128:5: note: no known conversion for argument 1 from ‘’ to ‘std::thread&&’

/usr/include/c++/4.6/thread:124:5: note: std::thread::thread()

/usr/include/c++/4.6/thread:124:5: note: candidate expects 0 arguments, 1 provided

like image 993
Cob013 Avatar asked Mar 15 '13 14:03

Cob013


1 Answers

You need a callable object taking no parameters, so

thread t3(&A::foo, &obj);

should do the trick. This has the effect of creating a callable entity which calls A::foo on obj.

The reason is that a non-static member function of A takes an implicit first parameter of type (possibly cv qualified) A*. When you call obj.foo() you are effectively calling A::foo(&obj). Once you know that, the above incantation makes perfect sense.

like image 106
juanchopanza Avatar answered Sep 19 '22 16:09

juanchopanza