2011-11-18 65 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; 
    }