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

正如上面的代碼,我想結合一類的成員函數void work(void)(我們將其命名爲測試) ,但會發生編譯器錯誤,表示無法確定使用哪個重載函數。如何綁定同名的成員函數的類,使用C++ 11的std ::綁定

我不能改變class Test因爲它屬於一個lib,如何實現我的目標?提前致謝!

+6

首選'auto f = [&test] {test.work(); };'對任何綁定表達式 –

+0

lambda確實比std :: bind方便實現我的目標,看到這些答案後 – debugman

+0

還要注意,通過使用'std :: function'而不是'auto',您支付了type-擦除 –

回答

5

爲什麼不跳過std::bind alltogehter和使用lambda?

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

作爲獎勵,你的可執行文件的大小將更小,你的編譯器有更容易的時間發送給打印機內聯的代碼。

+0

謝謝,它的工作原理。只是因爲我對C++ 11〜不是很熟悉 – debugman

3

通過它投射到正確的類型:

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

謝謝,但似乎該解決方案不適用於編譯錯誤C2562:「std :: _ Callable_obj Test *>,false> :: _ ApplyX「:」void「函數返回值c:\ program files(x86)\ microsoft visual studio 12.0 \ vc \ include \ xrefwrap 283 – debugman

1

當推斷模板參數綁定,編譯器是不是在上下文中,函數重載解析 - 要簡單化它,它也沒有還有那麼多。

在推導出第一個參數確實是成員函數指針的名稱後,它發現有兩個函數具有相同名稱但是具有不同類型。

在這個階段,他們都同樣有效候選人(從模板參數推導點),因此它的曖昧

靜態澆鑄消歧,因爲我們正在推動的編譯器超越的階段,它有推導一個模板類型 - 我們承擔了模板類型推演的責任 - 通過指定static_cast中的類型。

所以現在只需要重載分辨率。

#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

謝謝,但似乎該解決方案不適用於編譯錯誤'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

是visual studio 12完全符合C++ 11嗎? –

+0

看來,Visual Studio 12並沒有實現所有的C++ 11功能,所以.. – debugman

1

試試這個(成員函數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

謝謝,它的工作原理! – debugman