在 C++11 中指定成员函数作为回调

2024-01-12

我有以下内容:

typedef std::function<bool (const std::string&)> SomethingCoolCb;

class ClassA
{
public:
    void OnSomethingCool(const SomethingCoolCb& cb)
    {
        _cb = cb;
    }

private:
    SomethingCoolCb _cb;
};

class ClassB
{
public:
    ClassB();
    bool Juggle(const std::string& arg);

private:
    ClassA _obj;
};

我想指定 ClassB::Juggle() 成员函数作为 ClassB::_obj 的回调。在 C++11 中执行此操作的正确方法是(在 ClassB 的构造函数中):

ClassB::ClassB()
{
    _obj.OnDoSomethingCool(
        [&](const std::string& arg) -> bool
        {
            return Juggle(arg);
        });
}

据我了解,编译器将从上面的 lambda 代码中创建一个 std::function 对象。因此,当调用回调时,它将调用 std::function::operator() 成员,然后调用 ClassB::Juggle(),而不是直接调用 ClassB::Juggle()。除非我对幕后发生的事情有误解,否则这一切似乎都有点低效。有没有更好的办法?


仅使用std::function如果你确实需要多态函数。否则将其作为模板。

使成员函数适应函子使用std::mem_fn进而bind第一个参数的对象,生成的仿函数可以用作您的回调。

Sample:

#include <string>
#include <functional>

template<typename F>
class ClassA
{
public:
    ClassA(F f) : _cb(f) {}

private:
    F _cb;
};

class ClassB
{
public:
    ClassB() 
  : _obj(std::bind(&ClassB::Juggle, this, 
                   std::placeholders::_1)) 
  {}
  bool Juggle(const std::string& arg) {return true;}
private:
    ClassA<decltype(std::bind(
                      std::declval<bool (ClassB::*)(const std::string&)>()
                      , std::declval<ClassB*>()
                      , std::placeholders::_1
                      ) ) > _obj;
};

int main()
{
  ClassB b;
  return 0;
}

这回避了功能成本,但代价却是极其丑陋。

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

在 C++11 中指定成员函数作为回调 的相关文章

  • 结构化绑定中缺少类型信息

    我刚刚了解了 C 中的结构化绑定 但有一件事我不喜欢 auto x y some func is that auto正在隐藏类型x and y 我得抬头看看some func的声明来了解类型x and y 或者 我可以写 T1 x T2 y
  • 调用 McAfee 病毒扫描引擎

    我收到客户的请求 要求使用他们服务器上的 McAfee 病毒扫描将病毒扫描集成到应用程序中 我做了一些调查 发现 McScan32 dll 是主要的扫描引擎 它导出各种看起来有用的函数 我还发现提到了 McAfee Scan Engine
  • 如何在 Cassandra 中存储无符号整数?

    我通过 Datastax 驱动程序在 Cassandra 中存储一些数据 并且需要存储无符号 16 位和 32 位整数 对于无符号 16 位整数 我可以轻松地将它们存储为有符号 32 位整数 并根据需要进行转换 然而 对于无符号 64 位整
  • std::list 线程push_back、front、pop_front

    std list 线程安全吗 我假设不是这样 所以我添加了自己的同步机制 我认为我有正确的术语 但我仍然遇到问题 每个函数都由单独的线程调用 Thread1 不能等待 它必须尽可能快 std list
  • C++11 删除重写方法

    Preface 这是一个关于最佳实践的问题 涉及 C 11 中引入的删除运算符的新含义 当应用于覆盖继承父类的虚拟方法的子类时 背景 根据标准 引用的第一个用例是明确禁止调用某些类型的函数 否则转换将是隐式的 例如最新版本第 8 4 3 节
  • 如何从 Visual Studio 将视图导航到其控制器?

    问题是解决方案资源管理器上有 29 个项目 而且项目同时具有 ASP NET MVC 和 ASP NET Web 表单结构 在MVC部分中 Controller文件夹中有大约100个子文件夹 每个文件夹至少有3 4个控制器 视图完全位于不同
  • std::vector 与 std::stack

    有什么区别std vector and std stack 显然 向量可以删除集合中的项目 尽管比列表慢得多 而堆栈被构建为仅后进先出的集合 然而 堆栈对于最终物品操作是否更快 它是链表还是动态重新分配的数组 我找不到关于堆栈的太多信息 但
  • 为什么 GCC 不允许我创建“内联静态 std::stringstream”?

    我将直接前往 MCVE include
  • 传递给函数时多维数组的指针类型是什么? [复制]

    这个问题在这里已经有答案了 我在大学课堂上学习了 C 语言和指针 除了多维数组和指针之间的相似性之外 我认为我已经很好地掌握了这个概念 我认为由于所有数组 甚至多维 都存储在连续内存中 因此您可以安全地将其转换为int 假设给定的数组是in
  • 用于 FTP 的文件系统观察器

    我怎样才能实现FileSystemWatcherFTP 位置 在 C 中 这个想法是 每当 FTP 位置添加任何内容时 我都希望将其复制到我的本地计算机 任何想法都会有所帮助 这是我之前问题的后续使用 NET 进行选择性 FTP 下载 ht
  • 人脸 API DetectAsync 错误

    我想创建一个简单的程序来使用 Microsoft Azure Face API 和 Visual Studio 2015 检测人脸 遵循 https social technet microsoft com wiki contents ar
  • C# 列表通用扩展方法与非通用扩展方法

    这是一个简单的问题 我希望 集合类中有通用和非通用方法 例如List
  • 使用 C# 中的 CsvHelper 将不同文化的 csv 解析为十进制

    C 中 CsvHelper 解析小数的问题 我创建了一个从 byte 而不是文件获取 csv 文件的类 并且它工作正常 public static List
  • 两个静态变量同名(两个不同的文件),并在任何其他文件中 extern 其中一个

    在一个文件中将变量声明为 static 并在另一个文件中进行 extern 声明 我认为这会在链接时出现错误 因为 extern 变量不会在任何对象中看到 因为在其他文件中声明的变量带有限定符 static 但不知何故 链接器 瑞萨 没有显
  • 两个类可以使用 C++ 互相查看吗?

    所以我有一个 A 类 我想在其中调用一些 B 类函数 所以我包括 b h 但是 在 B 类中 我想调用 A 类函数 如果我包含 a h 它最终会陷入无限循环 对吗 我能做什么呢 仅将成员函数声明放在头文件 h 中 并将成员函数定义放在实现文
  • 为什么使用小于 32 位的整数?

    我总是喜欢使用最小尺寸的变量 这样效果就很好 但是如果我使用短字节整数而不是整数 并且内存是 32 位字可寻址 这真的会给我带来好处吗 编译器是否会做一些事情来增强内存使用 对于局部变量 它可能没有多大意义 但是在具有数千甚至数百万项的结构
  • 为什么 isnormal() 说一个值是正常的,而实际上不是?

    include
  • 编译时展开 for 循环内的模板参数?

    维基百科 here http en wikipedia org wiki Template metaprogramming Compile time code optimization 给出了 for 循环的编译时展开 我想知道我们是否可以
  • 相当于Linux中的导入库

    在 Windows C 中 当您想要链接 DLL 时 您必须提供导入库 但是在 GNU 构建系统中 当您想要链接 so 文件 相当于 dll 时 您就不需要链接 为什么是这样 是否有等效的 Windows 导入库 注意 我不会谈论在 Win
  • Mono 应用程序在非阻塞套接字发送时冻结

    我在 debian 9 上的 mono 下运行一个服务器应用程序 大约有 1000 2000 个客户端连接 并且应用程序经常冻结 CPU 使用率达到 100 我执行 kill QUIT pid 来获取线程堆栈转储 但它总是卡在这个位置

随机推荐

  • 如何使用xsl number对元素进行计数

    下面我使用xsl number 我想按顺序计算章节 如下所示 XML
  • 如何在Python中将RGBA图像转换为灰度图像?

    我有形状数组 height width 4 即 RGBA 格式 我想将其转换为灰度 原始数组的 RGB 值为 0 并且图片完全基于白色背景上的 alpha 值进行渲染 因此将其转换为灰度的传统方法会失败 例如 cv2 cvtColor im
  • Windows docker image vm 中的 ElasticSearch 最大映射计数

    我是 Docker 和 Elasticsearch 的新手 我使用的是 Windows 7 机器 我在用docker compose up启动 docker 容器 我的 yml 文件有 elasticsearch image elastic
  • 如何将 Spatial Solr 添加到 Solrnet 查询

    我正在我的 Windows 机器上使用 jetty 运行 Solr 我已经下载了空间 Solr 插件 http www jteam nl news spatialsolr我终于成功启动并运行了 我还使用 Solrnet 从我的 asp ne
  • 不实现 IEnumerable 支持 foreach 的示例

    我正在看这个博客 http blogs msdn com b kcwalina archive 2007 07 18 ducknotation aspx这解释了foreach无需实施即可支持IEnumerable 但没有深入讨论实现的细节
  • Swift 中带有 inout 参数的方法如何在 Objective-C 中使用?

    I want func foo inout stop Bool gt Void 在我的 Objective C 部分中使用 但它永远不会在 Module Swift h 标头中生成 如果我用 objc 标记它 方法不能标记 objc 因为参
  • Drupal Views 将每个分类限制的最新内容显示到一个节点

    我想创建一个视图 其中显示所有 5 个分类术语 然后显示最新发布的节点 但这受到 1 的限制 例如 税收条款 1最新节点发布 税务条款 2最新节点发布 etc etc 目前 我按分类术语进行分组 因此它显示所有已发布的节点 然后按发布日期降
  • 使用 @ControllerAdvice 测试 @RestController

    我的问题与测试 Spring RestController 相关 它也使用 ControllerAdvice 和 ExceptionHandler 这是代码 ControllerAdvice类 ControllerAdvice public
  • 按类名获取所有元素并更改类名

    我想 扫描文档以查找具有特定类名的所有元素 对该元素的innerHTML 执行一些关键功能 更改该元素的类名 这样如果我稍后再进行一次扫描 就不会重做该元素 我认为这段代码可以工作 但由于某种原因 它在第一个实例之后打破了循环 并且元素的类
  • 有效的 Unicode 字符串可以包含 FFFF 吗? Java/CharacterIterator 损坏了吗?

    这是摘录自java text CharacterIterator http docs oracle com javase 8 docs api java text CharacterIterator html文档 This interfac
  • 检查整数序列是否递增

    我只部分地解决了下面的问题 给定一个整数序列 检查是否可以通过删除不超过一个元素来获得严格递增的序列 Example sequence 1 3 2 1 almostIncreasingSequence sequence false sequ
  • 为所有任务获取自定义参数?

    我想将一个参数传递给 rake 而与我运行的任务无关 例如 rake my arg foo rake my arg foo install rake my arg foo upgrade rake my arg foo bar 有没有办法做
  • 映射器是适配器模式的一个版本

    我一直在尝试了解适配器模式 在所有模式中 我最难想象它的用途 我想我明白所实现的目标 对我来说 它将一个对象转换为另一个接口 以便客户端可以使用它 在我看到的示例中 它们是有道理的 但我觉得我可以使用映射器来实现相同的目的 该映射器接受一个
  • 如何强制 cmake 使用没有完整路径的 cl.exe?

    我正在构建一个使用 CMake 的开源项目 kst v2 0 8 我使用 CMake v2 8 12 2 和 MSVC 2008 作为编译器 并生成 NMake makefile 以在命令行上构建它 我可以通过此设置成功构建它 这些版本是强
  • 自修改代码的用例?

    On a 冯 诺依曼架构 http en wikipedia org wiki Von Neumann architecture 程序和数据都存储在内存中 因此程序可以自行修改 这对程序员有用吗 你能举一些例子吗 变质 我想到的一个 有问题
  • ChartJS 轴刻度回调函数中的条件未返回预期的标签

    我有一个包含一年中每一天数据的图表 我想将 x 轴简单地显示为月份 我设置了以下回调函数 它 粗略地 从标签集中获取月份 检查它是否已经存在 如果不存在 则将其作为轴标签返回 let rollingLabel function label
  • 创建一个触发器,在更新列时将值插入到新表中

    我一直在此处查看有关触发器的一些先前答案 但找不到我确切需要的内容 但我确信我的问题之前已被提出 回答过 我正在尝试跟踪表 1 中的列和列的任何更改 如果此值发生变化 我想通过将现有值和新值插入到带有日期的不同表中来跟踪这些值 我一直在考虑
  • C# 更改文本框中一个字符的颜色

    C WPF 如何仅更改文本框中一个字符的颜色 示例 Word Hello H 的颜色变为红色 您不能使用文本框执行此操作 但可以使用 Richtextbox WPF RichTextBox 教程 http www c sharpcorner
  • 如何从 DataGrid 获取单元格?

    我有一个 DataGrid net Framework 3 5 WPFToolKit 我想更改某些单元格的边框 左或右 一个 两个或三个 那么我怎样才能访问单个单元呢 这可能吗 我找到了一些解决方案 但它们适用于 net 4 您可以扩展 D
  • 在 C++11 中指定成员函数作为回调

    我有以下内容 typedef std function