gpt4 book ai didi

c++ - 在 C++ 中将 lambda 表达式作为成员函数指针传递

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:25:52 24 4
gpt4 key购买 nike

我有一个框架函数,它需要一个对象和一个成员函数指针(回调),如下所示:

do_some_work(Object* optr, void (Object::*fptr)()); // will call (optr->*fptr)()

如何将 lambda 表达式传递给它?想做这样的事情:

class MyObject : public Object
{
void mystuff()
{
do_some_work(this, [](){ /* this lambda I want to pass */ });
}
};

这一切的意义在于不要用回调扰乱 MyObject 类的接口(interface)。

UPD我无法以任何方式改进 do_some_work,因为我不控制框架,而且因为实际上它不是一个函数,而是有数百个。整个框架基于该类型的回调。没有 lambda 的常见用法示例:

typedef void (Object::*Callback)();
class MyObject : public Object
{
void mystuff()
{
do_some_work(this, (Callback)(MyClass::do_work));
}
void do_work()
{
// here the work is done
}
};

解决方案 这是我基于 Marcelo 的回答的解决方案:

class CallbackWrapper : public Object
{
fptr fptr_;
public:
CallbackWrapper(void (*fptr)()) : fptr_(fptr) { }
void execute()
{
*fptr_();
}
};

class MyObject : public Object
{
void mystuff()
{
CallbackWrapper* do_work = new CallbackWrapper([]()
{
/* this lambda is passed */
});
do_some_work(do_work, (Callback)(CallbackWrapper::execute));
}
};

自从我们创建了 CallbackWrapper 之后,我们就可以在异步使用回调的情况下控制它的生命周期。感谢大家。

最佳答案

这是不可能的。构造 (optr->*fptr)()要求 fptr 是指向成员的指针。如果do_some_work在您的控制之下,将其更改为采用与 lambda 函数兼容的内容,例如 std::function<void()>或参数化类型。如果它是一个不受您控制的遗留框架,您可以包装它,如果它是一个函数模板,例如:

template <typename Object>
do_some_work(Object* optr, void (Object::*fptr)());

然后,您可以实现一个包装器模板:

template <typename F>
void do_some_work(F f) {
struct S {
F f;
S(F f) : f(f) { }
void call() { f(); delete this; }
};
S* lamf = new S(f);
do_some_work(lamf, &S::call);
}

class MyObject // You probably don't need this class anymore.
{
void mystuff()
{
do_some_work([](){ /* Do your thing... */ });
}
};

编辑:如果 do_some_work 异步完成,您必须分配 lamf在堆上。为了安全起见,我已经相应地修改了上面的代码。感谢@David Rodriguez 指出这一点。

关于c++ - 在 C++ 中将 lambda 表达式作为成员函数指针传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11901084/

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