2014-10-03 92 views
2

我有一個結構稱爲富其中包含調用任何方法將其傳遞和返回值的函數。通個人會員和非成員函數指針作爲參數

struct Foo 
{ 
    unsigned char fooFunc(unsigned char param, unsigned char(getValueMethod)(const unsigned char)) 
    { 
     return getValueMethod(param); 
    } 
}; 

我有一個名爲barFunc方法...

static unsigned char barFunc(const unsigned char paramA) 
{ 
    return paramA * 2; 
} 

...可以很好地傳遞給fooFunc

Foo foo1; 
foo1.fooFunc(10, &barFunc); 

但我也想fooFunc接受成員函數,像bazFunc ....

struct Baz 
{ 
    unsigned char bazFunc(const unsigned char paramB) 
    { 
     return paramB * 3; 
    } 
}; 

...被這樣調用...

Foo foo2; 
Baz baz; 
foo2.fooFunc(10, ?????); 

...但這是無效的。

我的一切都在傳遞成員函數參數的對象體內發現談論知道什麼類的對象來自之前的叫法,這意味着我將不得不創建2個功能,而不是一個。

有沒有一種方法,我還沒有找到,這將只需要1 fooFunc的方法,但將支持非成員和成員函數?

+0

你可以使用C++ 11? – 2014-10-03 10:14:15

+1

不,我不能..... – Beakie 2014-10-03 10:14:30

+0

你想'的boost :: bind'(綁定了'this'指針)和模板可調用。從技術上講,這將導致多個'fooFunc '---方法---成員函數,但只有一個'fooFunc'成員函數模板! – 2014-10-03 10:15:27

回答

1

交C++ 11,按照其他的答案

預C++ 11:

#include <iostream> 
#include <functional> 


using namespace std; 

struct foo_holder { 

    template<class T> 
    unsigned char foo(unsigned char v, T f) { 
     return f(v); 
    } 

}; 

unsigned char bar(unsigned char param) { 
    return param * 2; 
} 

struct baz { 
    unsigned char bar(unsigned char param) { 
     return param * 3; 
    } 
}; 

int main() 
{ 
    cout << "Hello World" << endl; 

    foo_holder f; 
    baz b; 

    cout << static_cast<int>(
    f.foo(6, bar) 
    ) << endl; 

    cout << static_cast<int>(
    f.foo(6, std::bind1st(std::mem_fun(&baz::bar), &b)) 
    ) << endl; 

    return 0; 
} 
+0

因爲我的代碼不是C++ 11,而且我不想實現boost,所以我會將其作爲我的答案(即使我不想創建2個函數,即使使用模板),因爲它是我實際實施的最佳工作解決方案。 – Beakie 2014-10-03 11:13:42

+0

只有一個'foo_holder :: foo'的定義 - 相當於你的'Foo :: fooFunc'。只是它是一個模板成員函數。 – 2014-10-03 11:19:54

+0

但是如果我用2個調用實現它,一個使用成員函數,另一個使用非成員函數,我會得到2個(編譯)函數,對吧? – Beakie 2014-10-03 11:29:28

3

採取boost::function<signature>合格boost::bind()

bool free_func(std::string const& arg) { ... } 

struct X { 
    bool mem_func(std::string const& arg) { ... } 
}; 

... 
typedef boost::function<bool (std::string const& name)> func_t; 

std::vector<func_t> funcs; 
X x; 

funcs.push_back(boost::bind(&X::mem_func, x, _1)); 
funcs.push_back(boost::bind(&free_func, _1)); 
1

用C++ 11或提高你的任務是很容易的結果 - 而是因爲你想擁有C++ 03的解決方案,那麼作爲建議的意見 - 使用模板成員函數:

struct Foo 
{ 
    template <typename Function> 
    unsigned char fooFunc(unsigned char param, Function getValueMethod) 
    { 
     return getValueMethod(param); 
    } 
}; 

然後用免費的功能例如,你不會改變什麼:

Foo foo1; 
foo1.fooFunc(10, &barFunc); 

隨着成員函數 - 只使用C++從C++ 03 :

#include <functional> 
Foo foo2; 
Baz baz; 
foo2.fooFunc(10, std::bind1st(std::mem_fun(&Baz::bazFunc), &baz));