我必须使用一些期望函数指针的遗留代码,比如说:
void LEGACY_CODE(int(*)(int))
{
//...
}
然而,我所拥有的功能在一个仿函数中:
struct X
{
Y member;
X(Y y) : member(y)
{}
int operator()(int)
{
//...
}
};
我应该如何修改/包装类X
,以便LEGACY_CODE
可以访问X::operator()(int)
中的功能?
答案 0 :(得分: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);
}
你可以看到这是怎么回事......
答案 1 :(得分:0)
一个简单的包装函数如下所示:
int wrapperfunction(int i) {
Functor f(params);
return f(i);
}
如果您希望能够将参数传递给仿函数本身,最简单的方法是让他们使用(brr)全局变量:
Functor functorForWrapperfunction;
int wrapperfunction(int i) {
functorForWrapperfunction(i);
}
// ...
void clientCode() {
functorForWrapperfunction = Functor(a,b,c);
legacyCode(wrapperfunction);
}
如果需要,可以使用带静态方法和静态成员的类来包装它。
答案 2 :(得分:0)
这是一个编译时解决方案。根据您的需要,这对您来说可能是一个限制太多的解决方案。
template<typename Func, int Param>
int wrapper(int i)
{
static Func f(Param);
return f(i);
}
答案 3 :(得分: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;
}