2015-11-05 11 views
6
class Test{ 
public: 

    int work(){ 
     cout << "in work " << endl; 
     return 0; 
    } 

    void work(int x){ 
     //cout << "x = " << x << endl; 
     cout << "in work..." << endl; 
    } 
}; 

int main(){ 
    Test test; 
    std::function<void()> f = std::bind(&Test::work, &test); 
    thread th(f); 
    th.join(); 
    return 0; 
} 

Come sopra codice, voglio legare funzione membro void work(void) di una classe (Diamo il nome Test) , ma si verifica l'errore del compilatore che dice che non è possibile determinare quale funzione sovrascritta utilizzare.Come associare una delle funzioni membro con lo stesso nome in una classe, con C++ 11 std :: bind

Non riesco a cambiare il Test di classe poiché appartiene a una lib, come raggiungere il mio obiettivo? Grazie in anticipo!

+6

Preferisci 'auto f = [& test] {test.work(); }; 'a qualsiasi espressione di binding –

+0

lambda è davvero conveniente di std :: bind per realizzare il mio obiettivo, dopo aver visto queste risposte – debugman

+0

Si noti inoltre che usando' std :: function' invece di 'auto' si paga il prezzo di tipo- la cancellazione –

risposta

5

Perché non saltare std::bind alltogehter e utilizzare un lambda?

auto fp = [&t]() { t.test()}; 

Come bonus, la dimensione del file eseguibile sarà più piccolo e il compilatore ha molto più facile il tempo di inline il codice se apropriate.

+0

Grazie, funziona. semplicemente perché non ho molta familiarità con C++ 11 ~ – debugman

3

gettandola al tipo corretto:

std::function<void()> f = std::bind(static_cast<int (Test::*)()>(&Test::work), &test); 
+0

Grazie, ma sembra che la soluzione non funzioni con l'errore di compilazione C2562: "std :: _ Callable_obj , Test *>, false> :: _ ApplyX ":" void "函数 返回 值 c: \ programmi (x86) \ microsoft visual studio 12.0 \ vc \ include \ xrefwrap 283 – debugman

1

Quando dedurre gli argomenti di template per legare, il compilatore non è in un contesto che permette la risoluzione funzione di sovraccarico - di essere semplicistico a questo proposito, non ha arrivato così lontano.

Avendo dedotto che il primo argomento è effettivamente il nome di un puntatore a funzione membro, rileva che esistono due funzioni con lo stesso nome ma di tipi diversi.

In questa fase, sono entrambi i candidati altrettanto validi (dal punto di detrazione modello di argomentazione), quindi è ambigua

A disambigua del cast statici perché stiamo spingendo il compilatore al di là della fase in cui si deve dedurre un tipo di modello: ci siamo assunti la responsabilità della deduzione del tipo di modello, specificando il tipo nello static_cast.

Quindi ora tutto ciò che deve fare è la risoluzione del sovraccarico.

#include <functional> 
#include <thread> 
#include <iostream> 

using namespace std; 

class Test{ 
public: 

    int work(){ 
     cout << "in work " << endl; 
     return 0; 
    } 

    void work(int x){ 
     //cout << "x = " << x << endl; 
     cout << "in work..." << endl; 
    } 
}; 

int main(){ 
    Test test; 

    // only overload resolution required here 
    auto fp = static_cast<int (Test::*)()>(&Test::work); 

    // type is now unambiguous and overload resolution is already done 
    std::function<void()> f = std::bind(fp, &test); 

    thread th(f); 
    th.join(); 
    return 0; 
} 
+0

Grazie, ma sembra che la soluzione non funzioni con l'errore di compilazione 'C2562:" std :: _ Callable_obj , Test *>, false> :: _ ApplyX ":" void "函数 返回 值 \t c: \ programmi (x86) \ microsoft visual studio 12.0 \ vc \ include \ xrefwrap \t 283 ' – debugman

+0

è Visual Studio 12 completamente compatibile con C++ 11? –

+0

Sembra che Visual Studio 12 non implementa tutte le funzionalità di C++ 11, quindi .. – debugman

1

provare questo (funzione PTR membro):

int main(){ 
    Test test; 
    typedef int(Test:: *WKPtr)(void); 
    WKPtr p = &Test::work; 
    std::function<int()> f = std::bind(p, &test); 
    f(); 
    return 0; 
} 
+0

Grazie, funziona! – debugman

Problemi correlati