2015-11-05 10 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; 
} 

Jak wyżej kod, chcę związać funkcji członka void work(void) z klasą (nazwijmy go Test) , ale pojawia się komunikat o błędzie kompilatora, który nie może określić, której funkcji należy użyć.Jak powiązać jedną z funkcji członka o tej samej nazwie w klasie, z C++ 11 std :: wiążą

Nie mogę zmienić testu klasy, ponieważ należy ona do biblioteki, jak osiągnąć mój cel? Z góry dziękuję!

+6

Preferuj "auto f = [& test] {test.work(); }; 'do dowolnego wyrażenia wiązania –

+0

lambda jest rzeczywiście wygodniejsza niż std :: bind do realizacji mojego celu, po zobaczeniu tych odpowiedzi – debugman

+0

Należy również zauważyć, że używając' std :: function' zamiast 'auto' płacisz cenę typu- wymazać –

Odpowiedz

5

Dlaczego nie pominąć std::bind alltogehter i użyć lambda?

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

Jako bonus, twój plik wykonywalny będzie mniejszy, a Twój kompilator będzie miał znacznie łatwiejszy czas na wstawienie kodu, jeśli jest odpowiedni.

+0

Dzięki, to działa. po prostu dlatego, że nie jestem zaznajomiony z C++ 11 ~ – debugman

3

Przez rzucając go do odpowiedniego typu:

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

Dzięki, ale wygląda na to, że rozwiązanie nie działa z błędem kompilacji C2562: "std :: _ Callable_obj , Test *>, false> :: _ ApplyX ":" void "函数 返回 值 c: \ program files (x86) \ microsoft visual studio 12.0 \ vc \ include \ xrefwrap 283 – debugman

1

Podczas wyciągania argumentów szablonu do wiążą, kompilator nie jest w kontekście, który pozwala rozdzielczości przeciążenie funkcji - być uproszczone, o tym, że nie ma dotarłem jeszcze daleko.

Po wydedukowaniu, że pierwszy argument jest rzeczywiście nazwą wskaźnika funkcji członka, stwierdza, że ​​istnieją dwie funkcje o tej samej nazwie, ale o różnych typach.

Na tym etapie, są jednakowo ważne kandydatów (z punktu do odliczenia szablon argument), więc jest to niejednoznaczne

statycznym disambiguates lane ponieważ jesteśmy pchania kompilator poza etap gdzie musi wyprowadzić typ szablonu - sami wzięliśmy odpowiedzialność za dedukcję typu szablonu - poprzez określenie typu w static_cast.

Teraz wszystko, co musisz zrobić, to zmienić rozdzielczość.

#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

Dzięki, ale wygląda na to, że rozwiązanie nie działa z błędem kompilacji 'C2562:" std :: _ Callable_obj , Test *>, false> :: _ ApplyX ":" void "函数 返回 值 \t c: \ program files (x86) \ microsoft visual studio 12.0 \ vc \ include \ xrefwrap \t 283 ' – debugman

+0

jest visual studio 12 w pełni zgodne z C++ 11? –

+0

Wygląda na to, że studio graficzne 12 nie implementuje wszystkich funkcji C++ 11, więc .. – debugman

1

spróbować tej funkcji (członek PTR):

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

Dzięki, działa! – debugman

Powiązane problemy