2011-11-18 52 views
0

我必須使用一些舊的代碼期待一個函數指針,讓我們說:使用函數對象雖然函數指針需要

void LEGACY_CODE(int(*)(int)) 
{ 
    //... 
} 

但是我具備的功能是一個仿函數中:

struct X 
{ 
    Y member;  
    X(Y y) : member(y) 
    {} 

    int operator()(int) 
    { 
     //... 
    } 
}; 

我應該如何修改/包裝類X以便LEGACY_CODE可以訪問X::operator()(int)內的功能?

+5

我們需要一個自動的「成員函數作爲回調」問題求解器。 –

回答

1

你的問題沒有意義。 誰的運營商你想打電話嗎?

X a, b, c; 

LEGACY_CODE(???); // what -- a(), b(), or c()? 

所以,總之,你不能。成員函數X::operator()不僅僅是該類的一個屬性,而是它與X類型的對象實例相關聯。

在此網站搜索「成員函數」和「回調」,以瞭解相關問題的可能方法的範圍。


最粗略的,而且很有可能不是安全的可直接使用的,解決方法,以提供一個免費的功能會是這樣的:

X * current_X; // ugh, a global 
int dispatch(int n) { current_X->operator()(n); } 

int main() 
{ 
    X a; 
    current_X = &a; 
    LEGACY_CODE(dispatch); 
} 

你可以看到這是怎麼回事...

+0

我很確定他知道成員函數是如何工作的。他詢問是否有辦法讓遺留代碼與新代碼兼容。 –

+0

@PaulManta:那又怎樣。一個類不是一個函數的神奇泛化,如果OP對此感到困惑,那麼這個答案是有道理的。如果OP知道另一方面,她應該清楚她想使用哪個實例。 –

0

一個簡單的包裝功能看起來像:

int wrapperfunction(int i) { 
    Functor f(params); 
    return f(i); 
} 

如果你想能夠通過參數T Ø函子本身,最簡單的方法就是偷偷他們使用(BRR)一個全局變量:

Functor functorForWrapperfunction; 
int wrapperfunction(int i) { 
    functorForWrapperfunction(i); 
} 
// ... 
void clientCode() { 
    functorForWrapperfunction = Functor(a,b,c); 
    legacyCode(wrapperfunction); 
} 

你可以用一個類的靜態方法,如果你想有一個靜態成員包裹。

0

這是一個編譯時解決方案。根據您的需要,這可能對您而言是一個太有限的解決方案。

template<typename Func, int Param> 
int wrapper(int i) 
{ 
    static Func f(Param); 
    return f(i); 
} 
+0

@ user92382我編輯回答。 –

0

一個線程安全的版本,受線程安全版本的影響,遺留代碼沒有用線程中的不同參數調用。

恕我直言,一個不能擺脫全球存儲。

#include <boost/thread.hpp> 
#include <boost/thread/tss.hpp> 

class AA 
    { 
    public: 
     AA (int i) : i_(i) {} 
     void operator()(int j) const { 
      static boost::mutex m; // do not garble output 
      boost::mutex::scoped_lock lock(m); 
      std::cout << " got " << j << " on thread " << i_ << std::endl; 
      Sleep(200); } 
     int i_; 
    }; 

// LEGACY 
void legacy_code(void (*f)(int), int i) { (*f)(i); } 

// needs some global storage through 
boost::thread_specific_ptr<AA> global_ptr; 

void func_of_thread(int j) 
    { 
    AA *a = global_ptr.get(); 
    a->operator()(j); 
    } 

void worker(int i) 
{ 
global_ptr.reset(new AA(i)); 
for (int j=0; j<10; j++) 
    legacy_code(func_of_thread,j); 
    } 


int main() 
    { 
    boost::thread worker1(worker,1) , worker2(worker,2); 
    worker1.join(); worker2.join(); 
    return 0; 
    }