2009-12-11 88 views
6

我需要調用一個需要函數指針的方法,但是我真正想傳遞給它的方法是一個函子。這裏是什麼,我試圖做一個例子:函數指針在C++中的成員函數

#include <iostream> 
#include "boost/function.hpp" 

typedef int (*myAdder)(int); 

int adderFunction(int y) { return(2 + y); } 

class adderClass { 
    public: 
    adderClass(int x) : _x(x) {} 
    int operator() (int y) { return(_x + y); } 

    private: 
    int _x; 
}; 

void printer(myAdder h, int y) { 
    std::cout << h(y) << std::endl; 
} 

int main() { 
    myAdder f = adderFunction; 

    adderClass *ac = new adderClass(2); 
    boost::function1<int, int> g = 
    std::bind1st(std::mem_fun(&adderClass::operator()), ac); 

    std::cout << f(1) << std::endl; 
    std::cout << g(2) << std::endl; 
    printer(f, 3); 
    printer(g, 4); // Is there a way to get this to work? 
} 

我一直沒能找到一種方式來獲得的最後一行,打印機(克,4),進行編譯。有沒有辦法讓這個工作?在我的控制中唯一的東西是方法「主」和類「adderClass」。

回答

0

像這樣:

template<typename AdderT> 
void printer(AdderT h, int y) { 
    std::cout << h(y) << std::endl; 
} 

而且,你不需要boost::function。你可以這樣做:

adderClass ac(2); 
    std::cout << f(1) << std::endl; 
    std::cout << ac(2) << std::endl; 
    printer(f, 3); 
    printer(ac, 4); 
+0

這將工作,但(我忘了提及),方法「打印機」是在代碼中,我不能改變。 – JamieC 2009-12-11 14:02:54

+0

我掌握的所有東西都是「main」方法和「adderClass」類。 – JamieC 2009-12-11 14:03:40

0

雖然boost函數的行爲與普通函數指針類似,但它是不同的類型。所以你不能只給函數指針分配一個boost函數。

在你的代碼,你可以簡單地用

typedef boost::function1< int, int > myAdder; 

更換

typedef int (*myAdder)(int); 

,一切會工作。

2

好吧,這裏是另一種嘗試:

class CallProxy 
{ 
public: 
    static adderClass* m_instance; 
    static int adder(int y) 
    { 
     return (*m_instance)(y); 
    } 
}; 

adderClass* CallProxy::m_instance = NULL; 


int main() { 
    myAdder f = adderFunction; 

    adderClass ac(2); 

    std::cout << f(1) << std::endl; 
    std::cout << ac(2) << std::endl; 
    printer(f, 3); 
    CallProxy::m_instance = &ac; 
    printer(CallProxy::adder, 4); 
} 

麻煩的是,你必須printer編譯爲具有接受一個函數指針,沒有別的,所以你必須把它的函數指針。有了函數指針,你就沒有人擁有你的實例。所以這個解決方案通過使用靜態數據成員來實現。

請注意,這使得此代碼不是線程安全的。兩個同時執行main的線程可能會在m_instance中放入兩個不同的東西。

+1

它也不可重入:如果'printer'調用'main',那麼你遇到了麻煩。但我認爲這是最好的,可以在限制條件下完成,至少是可移植的。對於非便攜式解決方案,您可以例如即時生成代碼。 – 2009-12-11 14:25:52

+0

@Steve Jessop:任何調用'main()'的東西都會導致不確定的行爲(§3.6.1/ 2:「程序中不應該使用函數main(3.2)。」) – 2009-12-11 14:39:39

+0

@Jerry Coffin - 嘗試超越這個愚蠢的例子的有限範圍。 – shoosh 2009-12-11 14:41:53