Подтвердить что ты не робот

С++ 11 Инициализация потока с помощью функций-членов, компилирующих ошибку

Я только начинаю использовать потоки С++ 11, и я боролся с (возможно, глупой) ошибкой. Это моя примерная программа:

#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;
}

Можно ли запустить поток из чистой функции-члена? Если это не так, как я могу обернуть мою функцию foo из объекта obj, чтобы иметь возможность создать такой поток? Спасибо заранее!

Это компиляция:

thread_test.cpp: В функции 'int main(): thread_test.cpp: 32: 22: error: нет соответствующей функции для вызова 'std:: thread:: thread()

thread_test.cpp: 32: 22: примечание: кандидаты:

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

/usr/include/С++/4.6/thread: 133: 7: note: неизвестное преобразование для аргумента 1 от 'до' void (A:: * & &)()

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

/usr/include/С++/4.6/thread: 128: 5: note: неизвестное преобразование для аргумента 1 из 'в' std:: thread &&

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

/usr/include/С++/4.6/thread: 124: 5: примечание: кандидат ожидает 0 аргументов, 1 предоставлен

4b9b3361

Ответ 1

Вам нужен объект с вызовом без параметров, поэтому

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

должен сделать трюк. Это приводит к созданию вызываемого объекта, который вызывает A::foo на obj.

Причина в том, что нестатическая функция-член из A принимает неявный первый параметр типа (возможно, cv) A*. Когда вы вызываете obj.foo(), вы фактически вызываете A::foo(&obj). Как только вы это знаете, вышеупомянутое заклинание имеет смысл.