具有不同参数的 C++ 成员函数指针 - 还是这很糟糕?

2024-03-26

尽管我担心你会告诉我这个话题已经被讨论过好几次了,但我还是敢问,因为我无法生成解决方案。也许我只是在寻找错误的东西......

假设我有一个从某些外部函数接收“模式”的函数。根据模式的不同,函数会调用同一对象的不同成员函数。对于没有任何参数的成员函数,这对我来说效果很好,但我没有找到如何将其扩展到带参数的成员。在现实世界的应用程序中,参数不是 int/float 而是更复杂的类,并且调用嵌套在不同的循环中,因此我需要多次放置 switch 语句,我认为这很难看。

问题A:是否可以在现有设计的基础上轻松添加对带参数成员函数的支持?如果是,如何做到这一点?如果可能的话,无需外部库...

问题 B:这是一个完全错误/糟糕的方法吗?我该如何做得更好?

非常感谢您的帮助和解释。

Chris

标题摘录:

typedef void (Object::*memberFunction)();

class Object
{
    void memberFnNoArg();
    void memberFnWithIntArg(int arg);
    void memberFnWithFloatArg(float arg);
}

.cpp 摘录:

void function()
{
    int mode = getModeFromSomewhere();

    int intArg = 33;
    float floatArg = 66.6;

    switch(mode)
    {
    case 1:
        process(&Object::memberFnNoArg);
        break;
    case 2:
        process(&Object::memberFnWithIntArg, ???); // how can I pass arg?
        break;
    case 3:
        process(&Object::memberFnWithFlaotArg, ???); // how can I pass arg?
        break;
    default:
        // do nothing;
    }

}

void process(Object::memberFunction func)
{
    Object object;
    // loops, called several times, ...
    (object.*func)(); // how do I handle different arguments?
}

将算法包装在函子中是正确的方法,并且std::function是标准库提供的一个很好的函子。

但使用boost::bind甚至std::bind正如 Tomek 所建议的,在我看来确实很丑陋,并且在绑定多个参数时很快就会失去控制。

如果您有最新的编译器,则可以使用 lambda,这使得 Tomek 的示例如下所示:

std::function<void(Object*)> f  =
    [](Object* const that){ that->memberFnNoArg(); };

int int_value = 22;
std::function<void(Object*)> f2 =
    [int_value](Object* const that){ that->memberFnIntArg(int_value); };

Object o;
f(&o);
f2(&o);

有几个字符可以设置 lambda,但成员访问语法非常自然,并且很明显如何进行更改。

当然,如果您确实愿意,可以将参数设置为对象的引用,但我更喜欢这里的指针。

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

具有不同参数的 C++ 成员函数指针 - 还是这很糟糕? 的相关文章

  • 我的 std::hash for std::tuples...有什么改进吗? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 有些人可能已经注意到 std hash 不支持元组 所以我添加了一个重载 它看起来比我到目前为止看到的解决方案 更好 有人有进一步减少这段代码的
  • 如何在 ASP.NET MVC 中将 XML 文件发送到客户端

    在 ASP NET MVC 中 我有一个数据库表 我想在某个视图页面上有一个按钮 如果某个用户单击该按钮 我的应用程序将生成包含数据库中所有行的 XML 文件 然后 应将包含 XML 的文件发送到客户端 以便用户看到下载弹出窗口 同样 我希
  • 采用 std::vector 或 std::array 的模板函数

    我有一个函数 当前接受 2 个向量 其中可以包含任何普通的旧数据 template
  • getline 之后返回到文件开头

    所以我已经从文件中读取了所有行 while getline ifile line logic 其中 ifile 是 ifstream line 是字符串 我的问题是我现在想再次使用 getline 并且似乎无法返回到文件的开头 因为运行 c
  • Boost MPI 在监听列表时不会释放资源?

    这是一个后续问题如何释放 boost mpi request https stackoverflow com questions 44078901 how do i free a boostmpirequest 我在监听列表而不是单个项目时
  • C# 中类似图的实现

    所以我有一个对象 我们称之为 Head 它有一个对象列表 C C1 C2 C3 T T1 T2 和 M M1 M2 并且所有这些都是相互关联的 例如 Head gt C1 C2 C3 T1 T2 M1 M2 T1 gt C1 C2 T2 g
  • 如何使用c#从数据桶中获取所有文档?

    如何获取数据桶中的所有文档 我尝试过一个示例 但我只能获得一个特定的文档 这是我的代码 CouchbaseClient oclient oclient new CouchbaseClient vwspace data bucket name
  • 如何通过 libwebsocket 发送异步数据?

    我正在将 Warmcat 的 libwebsocket C 库用于小型 Websocket 服务器 我已经启动并运行了这些示例 并且可以发送数据以响应从 websocket 接收数据 例如回显发送的反向字节 但是 我无法弄清楚如何在不使用
  • C++ 指针和对象实例化

    这有效 MyObject o o new MyObject 而这并不 MyObject o new MyObject Why 关键词new 返回一个指针 http msdn microsoft com en us library kewsb
  • 无法将参数从 `const char *` 转换为 `char *`

    鉴于此代码 void group build int size std string ips Build the LL after receiving the member list from bootstrap head new memb
  • 为什么像 BindingList 或 ObservableCollection 这样的类不是线程安全的?

    我一次又一次发现自己必须编写 BindingList 和 ObservableCollection 的线程安全版本 因为当绑定到 UI 时 这些控件无法从多个线程更改 我想理解的是why情况就是这样 这是设计错误还是故意的 问题是设计一个线
  • QSpinBox 输入 NaN 作为有效值

    我正在尝试扩展 QSpinBox 以能够输入 NaN 或 nan 作为有效值 根据文档 我应该使用 textFromValue valueFromText 和 validate 函数来完成此操作 但我无法让它工作 因为它仍然不允许我输入除数
  • 使用 OleDbCommand / OleDbDataAdapter 读取 CSV 文件

    我不明白为什么 但是当我使用 OleDbDataAdapter 或 OleDbCommand 读取 CSV 文件时 在这两种情况下 生成的数据结构良好 它识别文件头中的列 但行数据都是空字符串 我之前已经成功进行过多次 CSV 处理 因此我
  • 从具有相同属性的另一个对象创建对象

    我有一个 C 对象 可以说有 20 个属性 它是数据契约的一部分 我还有另一个具有类似属性的业务实体 我想从响应对象中填充该实体 除了将一个对象的每个属性分配给另一个对象的相应属性之外 还有其他方法可以做到这一点吗 是的 看看自动映射器 h
  • 在 C# 命令行应用程序中包含并执行 EXE

    所以我找到了一个很棒的小 EXE 命令行应用程序 我们将其称为 program exe 它输出一些我想用 C 操作的数据 我想知道是否有一种方法可以将program exe 打包 到我的Visual Studio项目文件中 这样我就可以将编
  • 如何重用具有稍微不同的 ProcessStartInfo 实例的 Process 实例?

    我有以下开始的代码robocopy https technet microsoft com en us library cc733145 aspx as a Process 我还需要进行数据库查询以确定每次需要复制哪些目录robocopy被
  • 使用任务的经典永无止境的线程循环?

    给出了一个非常常见的线程场景 宣言 private Thread thread private bool isRunning false Start thread new Thread gt NeverEndingProc thread S
  • 检查一个数是否是完全平方数?

    我认为以下代码存在精度问题 bool isPerfectSquare long long n long long squareRootN long long sqrt n 0 5 return squareRootN squareRootN
  • 如何通过API退出Win32应用程序?

    我有一个使用 Win32 API 编写的 C Win32 应用程序 我希望强制它在其中一个函数中退出 有没有类似的东西Exit or Destroy or Abort 类似的东西会终止它吗 哎呀呀呀呀呀呀 不要做任何这些事情 exit 和
  • 创建进程默认浏览器

    我目前正在使用 ShellExecute 打开 在用户浏览器中打开 URL 但在 Win7 和 Vista 中遇到了一些麻烦 因为该程序作为服务运行提升 我想获取线程 id 因此 ShellExecute 无法获取线程 id 因此我开始使用

随机推荐

  • VSCODE 代码片段 PHP 自动填充命名空间

    我正在尝试创建一个VSCode 代码片段 https code visualstudio com api language extensions snippet guide for PHP https php net自动放置命名空间 基于文
  • 将特定文件的不同内容保留在 Git 分支中

    我有一个config php不同分支的内容应该不同 例如testing and master 我在另一个问题里问过 防止将 master 中的文件与 Git 合并 https stackoverflow com questions 1077
  • 如何优化4英寸兼容3.5英寸的屏幕尺寸

    我用故事板制作了一个4英寸的应用程序 但我发现我也必须支持 3 5 英寸屏幕 所以我转到故事板并单击将显示尺寸从 4 英寸切换到 3 5 的按钮 因为在 3 5 英寸中我的应用程序在底部被切断 不过我完成了 3 5 英寸的设计 又回到了 4
  • 如何使用 thymeleaf 在列表中添加对象?

    我在会话中有一个对象 例如一个部门 这个部门有子对象 我得到了它的子对象列表 现在我想在这个列表中添加这个部门对象 这在服务器端非常简单 但是可以吗这个在百里香叶里 是的 可以在 Thymeleaf 中执行此操作 因为它使用对象图导航语言
  • 如何将 git 集成到 m2eclipse 中?

    我正在尝试 m2eclipse 我发现它有一些功能可以直接从 SCM 签出 Maven 项目 根据这一页 http www sonatype com books m2eclipse book reference creating html
  • 在Android上通过Intent启动Huawei Petal Maps Directions

    是否可以推出华为花瓣地图 使用意图从 A 点导航到 B 点 就像谷歌地图一样 如果是 怎么办 是的 您可以使用 Intent 来启动 Petal Map 应用程序 然后使用应用程序中的导航功能 深层链接示例 mapapp navigatio
  • 无法更新到 Android Studio gradle 1.4 插件

    In my build gradle I have buildscript repositories mavenCentral dependencies classpath com android tools build gradle 1
  • 显示/隐藏下拉菜单

    这是我的代码
  • Visual Studio Code 插件(格式/拼写检查)

    使用新的 Visual Studio Code 编辑器与 1 这是not完整的 Visual Studio IDE 但基于atom io 的代码编辑器 我想安装专门用于拼写检查和格式化代码的插件 我怎样才能做到这一点 我已按照此处的说明进行
  • Office 2013 功能区和 .Net?

    我知道 Office 功能区自 2003 年以来经历了相当大的变化 并且我在 2010 年对功能区进行了一些适度的自定义 问 我看到了许多对 Net 的引用 特别是 C 和 Office Ribbon 这很大程度上只是 也许 动态定制吗 我
  • 如何使用单个查询列出查询的行或显示“无记录”

    如何列出查询的记录并在使用单个查询未返回行时显示 无记录 目前我正在使用COUNT 查询或使用mysql num rows 功能 然后在不同的结果集中另一个查询来列出数据 您能告诉我是否可以通过单个查询完成相同的任务吗 重要的 我假设OP使
  • “JQuery”类型的值不存在属性“jqGrid”

    我将 Typescript 与 jqGrid 和 jQuery 一起使用 在下面一行 jQuery this jqGrid editGridRow rowid 我收到消息 JQuery 类型的值不存在属性 jqGrid 关于如何纠正这个问题
  • 使用 Spring boot 的 Ehcache 在测试环境中不起作用

    我正在使用 Spring boot 1 4 2 RELEASE 和 Ehcache 2 4 3 缓存正在开发环境中使用 但在其他环境 测试和生产 中没有使用 命中 代码如下 pom xml
  • libdtrace 缓冲输出

    我正在尝试通过 libdtrace 使用 dtrace 在 Snow Leopard 上 10 6 4 我想在我自己的程序中捕获 dtrace 脚本的打印输出 一种方法是将输出转到临时文件并从那里读取 但是 libdtrace 支持回调函数
  • Quill.js:制作自定义链接格式 - 或 - 具有相同标签名称的自定义格式

    我正在使用鹅毛笔1 0 0 rc 1 如何制作几种不同类型的链接格式 我制作了三种不同类型的链接格式 添加了data link type属性 当我创建链接时 一切都很好 但是 当我使用将内容重新加载到编辑器中时pasteHTML 自上次注册
  • __zone_symbol__currentTask 错误

    我收到错误 zone symbol currentTask type microTask state notScheduled source Promise then zone angular cancelFn null runCount
  • 单击按钮时使球弹起

    I wrote a program to move a ball when a button is clicked It is a part of experiment for a bigegr project Here is the sc
  • 使用 LINQ to SQL SubmitChanges() 时,什么会导致 SqlDateTime 溢出?

    在我的代码中 我将多个对象添加到存储库中 我尝试在所有循环结束时运行一次存储库 Save 函数 并在添加每个对象后调用它 但无论哪种方式 当存储库 Save 中的 db SubmitChanges 时 我仍然会遇到 SqlDateTime
  • 事件可以声明为静态吗?如果可以,如何声明以及为什么

    我想知道我们是否可以将事件声明为静态 如果可以 为什么以及此类声明的应用 请提供样品 眼见为实 您可以创建静态事件 使用它们的方式与普通事件相同 只不过它是在类内的静态上下文中使用 public class MyClass public s
  • 具有不同参数的 C++ 成员函数指针 - 还是这很糟糕?

    尽管我担心你会告诉我这个话题已经被讨论过好几次了 但我还是敢问 因为我无法生成解决方案 也许我只是在寻找错误的东西 假设我有一个从某些外部函数接收 模式 的函数 根据模式的不同 函数会调用同一对象的不同成员函数 对于没有任何参数的成员函数