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

2023-12-24

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

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 类的接口。

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
    }
};

SOLUTION这是我根据马塞洛的回答提出的解决方案:

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 指出了这一点。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 lambda 表达式作为 C++ 中的成员函数指针传递 的相关文章

随机推荐

  • 如何使用 LibGit2Sharp 向 VSTS 进行身份验证?

    我正在尝试使用 LibGit2Sharp 克隆 VSTS Visual Studio Team Services 存储库 我正在设置一个CredentialsHandler and UsernamePasswordCredentials代表
  • Primefaces 保存/传递过滤后的数据表结果列表

    目前 我正在使用具有排序 过滤功能的数据表成功地显示数据库中的图像元数据 在我的数据表下方 我使用第三方图像封面成功地显示了我的图像 http www jacksasylum eu ContentFlow http www jacksasy
  • 引导日期选择器

    我试图让引导日期选择器突出显示在下拉日期选择器中选择的日期 它目前没有这样做 我错过了什么 div class input append date div
  • 根据控制器中的变量显示或隐藏元素 - Ionic

    据我所知 这可能更多的是 AngularJS 问题 而不是 Ionic 特定问题 我的一个视图中有一个按钮
  • 获取个人应用代码并显示

    我正在尝试获取应用程序代码并显示它 例如 如果按钮 X 启动一个新活动 则 textView 显示整个方法 我只到达了如何以 HTML 格式显示代码这个问题 https stackoverflow com questions 1529068
  • 跟踪电子中的窗口大小

    我今天才开始玩 Electron 我需要能够获取可用的窗口大小 并在窗口大小调整时更新它 看起来这并不像传统的 JS 应用程序那么简单 跟踪窗口大小的推荐方法是什么 目前 我有我的主进程和一个渲染器 不打算一次打开超过 1 个渲染器 窗口
  • 如何从命令行发送电子邮件?

    我想从命令行快速发送电子邮件 我意识到可能有多种不同的方法可以做到这一点 我正在寻找一种从 Linux 终端 可能是 bash shell 但任何东西都可以 执行此操作的简单方法 以及在 Windows 上执行此操作的替代方法 我希望能够直
  • 如何在 UML 序列图中表示监听器

    在序列图中 如何表示事件触发的侦听器 它不仅仅是常规方法调用 因此这样显示似乎不正确 我尝试制作包含 JMS 侦听器的系统的序列图 我可以通过系统对 JMS 队列的 send 调用来启动生命线 将调用 send 的系统显示为业务参与者 或者
  • Django 克隆递归对象

    以前 当我想递归地克隆对象时 我遇到了问题 我知道克隆对象的简单方法是这样的 obj Foo objects get pk
  • Swift 中何时使用静态常量和变量?

    有一些帖子介绍如何编写代码static constant and static variable在斯威夫特 但不清楚什么时候使用static constant and static variable而不是constant and varia
  • (InvalidRequestException) 调用 GetQueryResults 时...从 Lambda Python 查询 Athena...无法读取结果

    我一直在尝试从我的 lambda 函数 Python3 8 查询 Athena 但尽管尝试添加 if else 语句来检查执行状态 但我不断收到相同的错误 并且在 aws 控制台和 cli 上总是出现相同的错误本地 这是 lambda 函数
  • 根据用户用于浏览的设备(android tab、iphone、ipad)动态更改 zend 中的布局和模板

    我正在开发一个应用程序 PC 杂志商店 我已经完成了 PC 的大部分工作 但客户端也希望在其他 Android 设备上有同样的东西 作为 Web 视图加载 由于这些设备的高度和宽度与PC不同 所以我需要以最简单的方式获取设备的尺寸和高度 以
  • 我也应该连接到 QNetworkReply::error() 吗?

    我创建了一个 POST 请求并连接到完成的 http qt project org doc qt 5 0 qtnetwork qnetworkreply html finished signal QNetworkReply reply ma
  • 从 Uri 打开文件,与 Android 中的位置无关

    我可以使用一些帮助来了解如何在 android 中打开文件 我的具体问题与打开图像文件有关 在我的应用程序中 用户使用他们选择的相机应用程序拍摄图像 然后我对返回的图像进行操作 根据手机 Android 版本和所选相机应用程序的不同 我会在
  • javascript正则表达式从字符串末尾到开头搜索

    是否可以使用正则表达式从字符串末尾到开头进行搜索 例如我有一个字符串 a2bba2b 我知道我需要最后一次出现 a2 并且让机器遍历可能很长的整个字符串似乎效率非常低 我知道针将位于字符串 haystack 末尾附近的某个位置 所以我想颠倒
  • 显示特定产品类别的 WooCommerce 购物车项目简短描述

    在 WooCommerce 中 我尝试添加购物车项目中特定类别的产品简短描述 I found 这段代码 https stackoverflow com questions 27900033 solution for short descri
  • 使用 Javascript 将油画/素描效果应用于照片

    我想使用javascript从照片开始模拟人体绘图效果 我一直在搜索几个进行图像处理的 js 库 主要是在画布上 但似乎没有人尝试过我正在寻找的东西 我认为用javascript实现这样的效果并不是不可能的 所以我想知道为什么我找不到任何已
  • 如何在点击链接时创建 iframe?

    我有一个网页 表格内有几个链接 其中一个链接位于 td 标记内 我想要一种调用 iframe 的方法 一旦用户单击链接 该 iframe 就会打开 当 iframe 弹出时 页面的其余部分将变得无响应 一旦用户退出 iframe 外部页面就
  • 从哪里可以获得 SQL Server Compact Edition 4? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 将 lambda 表达式作为 C++ 中的成员函数指针传递

    我有一个框架函数 它需要一个对象和一个成员函数指针 回调 如下所示 do some work Object optr void Object fptr will call optr gt fptr 我怎样才能将 lambda 表达式传递给它