gpt4 book ai didi

C++ Callback -- 如何解耦回调类型

转载 作者:搜寻专家 更新时间:2023-10-31 00:45:25 24 4
gpt4 key购买 nike

例如,在下面的伪代码中,B类需要通过B::m_cb成员调用A::Action()。

目标是,如何制作一个通用的非模板回调类,因此“B”不必是模板,并且“CallBack”可以包含任何类型的函数签名。

我以前用过这样的代码,但现在找不到那个实现了。我只记得:
- “回调”本身不是模板,但它包含成员模板
- 辅助函数模板 make_callback 将实例化 CallBack 对象

谁能指点一下?

Class A
{
public:
void Action(){//...};
};

class CallBack
{
//...
// CallBack it self it is a NOT a template
// It can wrap member template though
};

class B
{
public:
void SetCallback(CallBack to){
m_cb = to;
}
void do_something()
{
//...
m_cb.Execute();
//...
}

private:
CallBack m_cb;

};

int main()
{
A obj1;
CallBack cb = make_callback(&obj1, &A::Action);
B obj2;
obj2.SetCallback(cb);
//....
obj2.do_something();
}

这是我从同一网站获得的示例代码。我试着稍微改进一下,让它可以容忍任意回调函数的返回类型。但它仍然无法处理任意数量的参数,如第 18 行所示。此外,T 是指向成员函数的指针,它应该依赖于 C。我不知道如何强制执行此操作。

#include <iostream>
#include <memory>

// INTERNAL CLASSES

class CallbackSpecBase
{
public:
virtual ~CallbackSpecBase() {}
virtual void operator()(...) const = 0;
};

template<class C, class T>
class CallbackSpec : public CallbackSpecBase
{
public:
CallbackSpec(C& o, T m) : obj(o), method(m) {}
/*line 18*/ void operator()(...) const { (&obj->*method)(); } // how to pass "..." into method(...)

private:
C& obj;
T method;
};

// PUBLIC API

class Callback
{
public:
Callback() {}

void operator()() { (*spec)(); }

template<class C, class T>
void set(C& o, T m) { spec.reset(new CallbackSpec<C, T>(o, m)); }

private:
std::auto_ptr<CallbackSpecBase> spec;
};

// TEST CODE

class Test
{
public:
void foo() { std::cout << "Working" << std::endl; }
void bar() { std::cout << "Like a charm" << std::endl; }
};

int main()
{
Test t;
Callback c;
c.set(t, &Test::foo);
c();
c.set(t, &Test::bar);
c();
}

最佳答案

您正在寻找的是 std::function (C++0x)/boost::function。这些使用类型删除使函数表现得像一流的对象。你可以这样做:

class A
{
public:
void Action() {//...};
};

class B
{
public:
template <typename Func>
void SetCallback(Func func) {
m_cb = func;
}

void do_something() {
m_cb(); // whatever function
}

private:
std::function<void()> m_cb; // anything callable with no arguments
};

int main()
{
A obj1;
B obj2;

obj2.SetCallback(make_callback(&obj1, &A::Action));
// or:
obj2.SetCallback(std::bind(&obj1, &A::Action)); // or boost::bind

obj2.do_something();
}

关于C++ Callback -- 如何解耦回调类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6849287/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com