2015-04-08 111 views
2

我一直在使用C++中的函數指針,似乎已經發現了一些問題。我通過一個簡單的例子來演示重現錯誤。函數指針在參數對象中使用函數

我的頭文件

class MyClass 
{ 
public: 
    void MyFunction(int i); 
    MyClass(); 
    ~MyClass(); 
}; 

和cpp文件

#include "MyClass.h" 
#include <iostream> 
#include <functional> 
using namespace std; 

MyClass::MyClass() 
{ 
    //doesn't work 
    function<void(int)> func = &MyClass::MyFunction; 
} 

void MyClass::MyFunction(int i) 
{ 
    cout << i << endl; 
} 

在cpp文件我想創建一個指向的MyFunction的構造。它在第506行的功能文件中給出了錯誤error C2664: 'void std::_Func_class<_Ret,int>::_Set(std::_Func_base<_Ret,int> *)' : cannot convert argument 1 from '_Myimpl *' to 'std::_Func_base<_Ret,int> *'。它對於無參數方法很好,但不適用於它們。有誰知道爲什麼,以及如何解決它?

+3

非靜態成員函數需要一個對象。 – chris

+0

所以我不能從課堂上做到這一點?或者有沒有辦法用我完全缺少的這個關鍵字來做到這一點? –

回答

3

您可以使用this並將正在構造的對象綁定到該函數。舉例來說,如果你的構造是這樣的:

MyClass::MyClass() 
{ 
    function<void(int)> func = bind(&MyClass::MyFunction, this, placeholders::_1); 
    func(6); 
} 

你創建了一個MyClass實例:

MyClass instance; 

然後6將被打印到標準輸出。

+0

這工作,謝謝。你能解釋一下佔位符:: _ 1是什麼嗎? –

+1

佔位符基本上是作爲[currying](http://stackoverflow.com/a/160286/2297365)函數的一種方式。所有非靜態成員函數實際上都有一個隱含的第一個參數,即類本身的一個實例。你正在做的是將一個實例綁定到第一個參數,而第二個參數未指定。佔位符爲您提供了表達這一點的語義。 – huu

+1

例如,如果放置一個'6'而不是佔位符,那麼函數將被完全指定,並且只能將其稱爲'func()'。這會打印出一個'6'到標準輸出。 – huu

3

您還可以在使用std::mem_fn C++ 11,它包裝一個成員函數/變量到一個可調用關閉

#include <iostream> 
#include <functional> 

class MyClass 
{ 
public: 
    MyClass() 
    { 
     auto func = std::mem_fn(&MyClass::MyFunction); 
     func(this, 42); // call it on the current instance 
    } 
    void MyFunction(int i) 
    { 
     std::cout << i << std::endl; 
    } 
}; 

int main() 
{ 
    MyClass foo; 
} 

或者,您可以明確指定要調用的成員函數指針的實例

MyClass() 
{ 
    auto func = &MyClass::MyFunction; 
    (this->*func)(42); // call it on the current instance 
} 

尤其要注意的是,std::function<void(int)>不能轉換成指向成員函數的指針。看到相關的Using generic std::function objects with member functions in one class 這就是爲什麼使用autostd::mem_fn擺脫所有的痛苦。

+1

這是一個很好的答案。它可以讓你把函數視爲C++對待它,作爲一個函數將類的實例作爲第一個參數,以及其後的所有其他參數。 – huu

+0

謝謝,我最近發現了'std :: mem_fn',我認爲這對於日常的C++工作來說是一個很好的包裝 – vsoftco