2013-03-15 17 views
13

Sto solo iniziando a utilizzare i thread C++ 11 e ho avuto un errore (probabilmente stupido). Questo è il mio programma di esempio:C++ 11 Inizializzazione del thread con errore di compilazione delle funzioni membro

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

E 'possibile avviare un thread da una funzione membro puro? Se non lo è, come posso avvolgere la mia funzione dall'oggetto obj per poter creare tale thread? Grazie in anticipo!

Questo è l'errore di compilazione:

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

Provate un semplice lambda: '[&]() {obj.foo();}'. [Codice completo qui] (http://liveworkspace.org/code/4Fh1lL$1). – BoBTFish

+0

+1: esempio di codice piccolo ma completo e messaggio di errore non elaborato. Tieni presente che la formattazione del frammento di codice qui su SO non gradisce le schede (ho risolto questo problema per te in questo post). – Angew

+0

Grazie Angew, cambierò sicuramente le schede nei post futuri. – Rob013

risposta

20

bisogno di un oggetto richiamabile prendere senza parametri, in modo da

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

dovrebbe fare il trucco. Questo ha l'effetto di creare un'entità richiamabile che chiama A::foo su obj.

Il motivo è che una funzione membro non statico di A accetta un primo parametro implicito di tipo (possibilmente qualificato cv) A*. Quando chiamate il numero obj.foo() chiamate in modo efficace A::foo(&obj). Una volta che lo sai, l'incantesimo di cui sopra ha perfettamente senso.

+0

Perfetto grazie! Mi dispiace aver ripubblicato una domanda esistente, probabilmente mi mancano i tag giusti. A proposito, ora funziona! – Rob013

+2

@ Rob013 Felice di averlo aiutato. In realtà, ho appena realizzato che questo non è spiegato molto bene nel duplicato. – juanchopanza

+0

@juanchopanza capisco il punto che qualsiasi funzione membro (non statica) prenderà il primo parametro implicito di quel tipo (questo puntatore di quell'istanza). Ma perché non funziona se passo l'oggetto come argomento (come hai fatto per assegnarli ai thread) per chiamare qualsiasi funzione membro ordinaria (ad esempio A :: foo (&obj);) Per favore dimmi di più su questo .. qualsiasi link per questo concetto andrà bene. Grazie ... –

Problemi correlati