2015-01-15 49 views
1

在下面顯示的簡單代碼中,有一個函數run7,它接收函數作爲參數。在main函數中,函數test被傳遞給它,它工作正常。但是,我的method2無法通過method1到此功能。它會導致錯誤:C++傳遞另一個方法作爲參數

main.cpp:24:15: error: cannot convert ‘A::method1’ from type ‘void (A::)(int)’ to type ‘void (*)(int)’ 
    run7(method1); 
      ^

我要打電話傳遞method1run7不改變run7結構。如何修復method2

#include <iostream> 

using namespace std; 

void run7 (void (*f)(int)) 
{ 
    f(7); 
} 

void test(int a) 
{ 
    cout<<a<<endl; 
} 

class A 
{ 
public: 

    int m=4; 

    void method1(int a) 
    { 
     cout<< a*m <<endl; 
    } 

    void method2() 
    { 
     run7(method1); 
    } 
}; 

int main() 
{ 
    run7(test); 
    return 0; 
} 
+0

函數指針是不是與方法指針相同。你需要多研究一下。 – Cameron

+0

你也許可以綁定或其他魔法。你的問題是method1是非靜態的,所以'method1'的類型是'void(A :: *)(int)',並且你想接受類型爲'void(*)(int)'的參數,這很清楚不是一回事。如果你真的想將method1傳遞給它,你必須使它靜態。 – Creris

回答

4

如果你看仔細的錯誤:

error: cannot convert ‘A::method1’ from type ‘void (A::)(int)’ to type ‘void (*)(int)’

你會看到,類型不同。這是因爲類方法沒有原始函數的類型 - 它們需要額外的對象才能被調用。由於調用method1需要A,因此無法獲取該代碼以進行編譯,這需要無法作爲原始函數指針傳入的存儲。

你可以做什麼,而不是爲改變run採取型擦除函子:

void run7 (std::function<void(int)> f) { 
    f(7); 
} 

然後在其中也通過在this函子通:

void method2() 
{ 
    run7(std::bind(&A::method1, this,   // option 1 
        std::placeholders::_1)); 
    run7([this](int x){ this->method1(x); }); // option 2 
} 
+0

option1是首選,但是:'錯誤:無法轉換'std :: bind(_Func &&,_BoundArgs && ...)[with _Func = void(A :: *)(int); _BoundArgs = {A * const}; typename std :: _ Bind_helper :: type>,std :: is_enum :: type>> :: value,_Func,_BoundArgs ...> :: type = std :: _ Bind (A *)>]((*&this))'from'std :: _ Bind_helper :: type {aka std :: _ Bind std :: _ Mem_fn (A *)>}'to'std :: function ' run7(std :: bind(&A :: method1,this));' – barej

+0

我假定method1不能是靜態的。可以綁定解決嗎? – barej

+0

謝謝。什麼'std :: placeholders'在這裏做? – barej

2

使run7函數模板,因此它可以使用任何可調用的對象。

然後,用一個lambda函數從method2調用它。

void method2() 
{ 
    run7([=](int arg){this->method1(arg)];}); 
} 

更新

您可以使用一個更好的版本的run7使用普遍引用和完美轉發,使其乾淨(感謝是由於@Quentin您的建議)。

template <typename F> 
void run7(F&& f) 
{ 
    std::forward<F>(f)(7); 
} 
+0

不要忘記使用通用的引用和完美的轉發爲乾淨的答案:) – Quentin

+0

@Quentin,我不追隨你的漂移。在這個例子中,普遍的引用和完美的轉發工作在哪裏? –

+0

在傳遞函數對象本身時,即'F && f'和'std :: forward (f)(7);'。 – Quentin

相關問題