在 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 中指定成员函数作为回调 的相关文章

随机推荐

  • 如何使用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