2013-03-15 12 views
13

Właśnie zaczynam używać wątków C++ 11 i walczyłem (prawdopodobnie głupio) o błąd. To jest mój przykładowy program:C++ 11 Inicjowanie wątków przy kompilacji funkcji składowych członkowskich

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

Czy to możliwe, aby rozpocząć wątek z czystego funkcji członkiem? Jeśli tak nie jest, w jaki sposób mogę zawinąć funkcję foo z obiektu obj, aby móc utworzyć taki wątek? Z góry dziękuję!

Jest to błąd kompilacji:

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

+3

Wypróbuj proste lambda: '[&]() {obj.foo();}'. [Pełny kod tutaj] (http://liveworkspace.org/code/4Fh1lL$1). – BoBTFish

+0

+1: Mały, ale pełny przykład kodu i pełny komunikat o błędzie. Po prostu zwróć uwagę, że formatowanie kodu tutaj na SO nie lubi kart (naprawiłem to dla ciebie w tym poście). – Angew

+0

Dzięki Angew, na pewno zmienię zakładki w kolejnych postach. – Rob013

Odpowiedz

20

Musisz wpłacone obiekt sobą nie parametry, więc

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

powinno załatwić sprawę. Powoduje to utworzenie jednostki, którą można wywołać, która wywołuje A::foo na na .

Powodem jest to, że niestatyczna funkcja składowa A przyjmuje domyślny pierwszy parametr typu (prawdopodobnie kwalifikowany cv) A*. Po wywołaniu obj.foo() skutecznie dzwonisz pod numer A::foo(&obj). Kiedy już to wiesz, powyższe zaklęcie ma sens.

+0

Doskonałe dzięki! Przykro mi, że przerzuciłem istniejące pytanie, prawdopodobnie brakuje mi odpowiednich tagów. Przy okazji, teraz działa! – Rob013

+2

@ Rob013 Cieszę się, że pomogło. Właściwie to po prostu zdałem sobie sprawę, że nie jest to dobrze wyjaśnione w duplikacie. – juanchopanza

+0

@juanchopanza rozumiem, że dowolna funkcja członkowska (nie statyczna) przyjmuje domyślny pierwszy parametr tego typu (ten wskaźnik tej instancji). Ale dlaczego nie działa, jeśli przekazuję obiekt jako argument (tak jak zrobiłeś to przypisując mu wątki) do wywoływania jakiejkolwiek zwykłej funkcji członka (np. A :: foo (&obj);) Proszę, powiedz mi więcej o tym .. dowolny link do tej koncepcji będzie dobrze. Dzięki .. –

Powiązane problemy