C++0x:在 std::map 中存储任何类型的 std::function

2023-11-21

我试图在地图中存储一组 std::function (在 GCC 4.5 下)

我想要得到两种东西:

  • 存储已传递参数的函数;那么你就拥有了 调用 f()
  • 存储不带参数的函数;那么你必须打电话 F(...)

我想我通过类 Command 和 Manager 实现了第一个:

class Command
{
  std::function<void()> f_;
  public:
    Command() {}
    Command(std::function<void()> f) : f_(f) {}

    void execute() { if(f_) f_(); }

};

class CommandManager
{
  typedef map<string, Command*> FMap;

  public :

  void add(string name, Command* cmd)
  {
     fmap1.insert(pair<string, Command*>(name, cmd));
  }

  void execute(string name)
  {
    FMap::const_iterator it = fmap1.find(name);
    if(it != fmap1.end())
    {
      Command* c = it->second;
      c->execute();
    }
  }

  private :

    FMap fmap1;

};

可以这样使用:

class Print{

   public:
   void print1(string s, string s1){ cout<<"print1 : "<<"s : "<<s<<" s1 : "<<s1<<endl; }
   int print2(){ cout<<"print2"<<endl; return 2;}

};

#include <string>
#include <functional>

int main()
{
  Print p = Print();

  function<void()> f1(bind(&Print::print1, &p, string("test1"), string("test2")));

  function<int()> f2(bind(&Print::print2, &p));

  CommandManager cmdMgr = CommandManager();
  cmdMgr.add("print1", new Command(f1));
  cmdMgr.execute("print1");

  cmdMgr.add("print2", new Command(f2));
  cmdMgr.execute("print2");

  return 0;
}

现在我希望能够做到这一点:

 int main()
 {
      Print p = Print();

      function<void(string, string)> f1(bind(&Print::print1, &p, placeholders::_1, placeholders::_2));

      CommandManager cmdMgr = CommandManager();
      cmdMgr.add("print1", new Command(f1));
      cmdMgr.execute("print1", string("test1"), string("test2"));

      return 0;
    }

有没有办法,例如使用类型擦除?


您可以使用动态转换来在运行时确定列表中函数的类型。 请注意,我添加了shared_ptr来消除原始示例中的内存泄漏。如果使用错误的参数调用execute方法(如果dynamic_cast产生0),也许您想抛出异常。

Usage:

void x() {}
void y(int ) {}
void main() {
    CommandManager m;
    m.add("print", Command<>(x));
    m.add("print1", Command<int>(y));
    m.execute("print");
    m.execute("print1", 1);
}

代码(带有可变参数模板支持,例如 gcc-4.5):

#include <functional>
#include <map>
#include <string>
#include <memory>

using namespace std;

class BaseCommand
{
public:
    virtual ~BaseCommand() {}
};

template <class... ArgTypes>
class Command : public BaseCommand
{
  typedef std::function<void(ArgTypes...)> FuncType;
  FuncType f_;
  public:
    Command() {}
    Command(FuncType f) : f_(f) {}
    void operator()(ArgTypes... args) { if(f_) f_(args...); }
};

class CommandManager
{
  typedef shared_ptr<BaseCommand> BaseCommandPtr;
  typedef map<string, BaseCommandPtr> FMap;
  public :

  template <class T>
  void add(string name, const T& cmd)
  {
     fmap1.insert(pair<string, BaseCommandPtr>(name, BaseCommandPtr(new T(cmd))));
  }

  template <class... ArgTypes>
  void execute(string name, ArgTypes... args)
  {
    typedef Command<ArgTypes...> CommandType;
    FMap::const_iterator it = fmap1.find(name);
    if(it != fmap1.end())
    {
      CommandType* c = dynamic_cast<CommandType*>(it->second.get());
      if(c)
      {
    (*c)(args...);
      }
    }
  } 

  private :
    FMap fmap1;
};

没有可变参数模板支持(例如 VS2010):

#include <functional>
#include <map>
#include <string>
#include <memory>

using namespace std;
class Ignored;

class BaseCommand
{
public:
    virtual ~BaseCommand() = 0 {};
};

template <class A1 = Ignored>
class Command : public BaseCommand
{
  typedef std::function<void(A1)> FuncType;
  FuncType f_;
  public:
    Command() {}
    Command(FuncType f) : f_(f) {}
    void operator()(const A1& a1) { if(f_) f_(a1); }
};

template <>
class Command<Ignored> : public BaseCommand
{
  typedef std::function<void()> FuncType;
  FuncType f_;
  public:
    Command() {}
    Command(FuncType f) : f_(f) {}
    void operator()() { if(f_) f_(); }
};

class CommandManager
{
  typedef shared_ptr<BaseCommand> BaseCommandPtr;
  typedef map<string, BaseCommandPtr> FMap;
  public :

  template <class T>
  void add(string name, const T& cmd)
  {
     fmap1.insert(pair<string, BaseCommandPtr>(name, BaseCommandPtr(new T(cmd))));
  }

  template <class A1>
  void execute(string name, const A1& a1)
  {
    typedef Command<A1> CommandType;
    FMap::const_iterator it = fmap1.find(name);
    if(it != fmap1.end())
    {
      CommandType* c = dynamic_cast<CommandType*>(it->second.get());
      if(c)
      {
        (*c)(a1);
      }
    }
  } 

  void execute(string name)
  {
    typedef Command<> CommandType;
    FMap::const_iterator it = fmap1.find(name);
    if(it != fmap1.end())
    {
      CommandType* c = dynamic_cast<CommandType*>(it->second.get());
      if(c)
      {
        (*c)();
      }
    }
  }
  private :
    FMap fmap1;
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++0x:在 std::map 中存储任何类型的 std::function 的相关文章

  • 检查两个数是否是彼此的排列?

    给定两个数字 a b 使得 1 例如 123 是 312 的有效排列 我也不想对数字中的数字进行排序 如果您指的是数字的字符 例如 1927 和 9721 则 至少 有几种方法 如果允许排序 一种方法是简单地sprintf将它们放入两个缓冲
  • 如何使 Windows 窗体的关闭按钮不关闭窗体但使其不可见?

    该表单有一个 NotifyIcon 对象 当用户单击 关闭 按钮时 我希望表单不关闭而是变得不可见 然后 如果用户想再次查看该表单 可以双击系统托盘中的图标 如果用户想关闭表单 可以右键单击该图标并选择 关闭 有人可以告诉我如何使关闭按钮不
  • 是否可以强制 XMLWriter 将元素写入单引号中?

    这是我的代码 var ptFirstName tboxFirstName Text writer WriteAttributeString first ptFirstName 请注意 即使我使用 ptFirstName 也会以双引号结束 p
  • C# 和 Javascript SHA256 哈希的代码示例

    我有一个在服务器端运行的 C 算法 它对 Base64 编码的字符串进行哈希处理 byte salt Convert FromBase64String serverSalt Step 1 SHA256Managed sha256 new S
  • 当我使用“control-c”关闭发送对等方的套接字时,为什么接收对等方的套接字不断接收“”

    我是套接字编程的新手 我知道使用 control c 关闭套接字是一个坏习惯 但是为什么在我使用 control c 关闭发送进程后 接收方上的套接字不断接收 在 control c 退出进程后 发送方的套接字不应该关闭吗 谢谢 我知道使用
  • 如何使用GDB修改内存内容?

    我知道我们可以使用几个命令来访问和读取内存 例如 print p x 但是如何更改任何特定位置的内存内容 在 GDB 中调试时 最简单的是设置程序变量 参见GDB 分配 http sourceware org gdb current onl
  • UML类图:抽象方法和属性是这样写的吗?

    当我第一次为一个小型 C 项目创建 uml 类图时 我在属性方面遇到了一些麻烦 最后我只是将属性添加为变量 lt
  • linux perf:如何解释和查找热点

    我尝试了linux perf https perf wiki kernel org index php Main Page今天很实用 但在解释其结果时遇到了困难 我习惯了 valgrind 的 callgrind 这当然是与基于采样的 pe
  • 使闭包捕获的变量变得易失性

    闭包捕获的变量如何与不同线程交互 在下面的示例代码中 我想将totalEvents 声明为易失性的 但C 不允许这样做 是的 我知道这是错误的代码 这只是一个例子 private void WaitFor10Events volatile
  • 当 contains() 工作正常时,xpath 函数ends-with() 工作时出现问题

    我正在尝试获取具有以特定 id 结尾的属性的标签 like span 我想获取 id 以 国家 地区 结尾的跨度我尝试以下xpath span ends with id Country 但我得到以下异常 需要命名空间管理器或 XsltCon
  • WPF 中的调度程序和异步等待

    我正在尝试学习 WPF C 中的异步编程 但我陷入了异步编程和使用调度程序的困境 它们是不同的还是在相同的场景中使用 我愿意简短地回答这个问题 以免含糊不清 因为我知道我混淆了 WPF 中的概念和函数 但还不足以在功能上正确使用它 我在这里
  • 指针问题(仅在发布版本中)

    不确定如何描述这一点 但我在这里 由于某种原因 当尝试创建我的游戏的发布版本进行测试时 它的敌人创建方面不起作用 Enemies e level1 3 e level1 0 Enemies sdlLib 500 2 3 128 250 32
  • 在 ASP.NET Core 3.1 中使用包含“System.Web.HttpContext”的旧项目

    我们有一些用 Net Framework编写的遗留项目 应该由由ASP NET Core3 1编写的API项目使用 问题是这些遗留项目正在使用 System Web HttpContext 您知道它不再存在于 net core 中 现在我们
  • 将自定义元数据添加到 jpeg 文件

    我正在开发一个图像处理项目 C 我需要在处理完成后将自定义元数据写入 jpeg 文件 我怎样才能做到这一点 有没有可用的图书馆可以做到这一点 如果您正在谈论 EXIF 元数据 您可能需要查看exiv2 http www exiv2 org
  • 如何将单个 char 转换为 int [重复]

    这个问题在这里已经有答案了 我有一串数字 例如 123456789 我需要提取它们中的每一个以在计算中使用它们 我当然可以通过索引访问每个字符 但是如何将其转换为 int 我研究过 atoi 但它需要一个字符串作为参数 因此 我必须将每个字
  • Discord.net 无法在 Linux 上运行

    我正在尝试让在 Linux VPS 上运行的 Discord net 中编码的不和谐机器人 我通过单声道运行 但我不断收到此错误 Unhandled Exception System Exception Connection lost at
  • 如何让Gtk+窗口背景透明?

    我想让 Gtk 窗口的背景透明 以便只有窗口中的小部件可见 我找到了一些教程 http mikehearn wordpress com 2006 03 26 gtk windows with alpha channels https web
  • C - 直接从键盘缓冲区读取

    这是C语言中的一个问题 如何直接读取键盘缓冲区中的数据 我想直接访问数据并将其存储在变量中 变量应该是什么数据类型 我需要它用于我们研究所目前正在开发的操作系统 它被称为 ICS OS 我不太清楚具体细节 它在 x86 32 位机器上运行
  • Process.Start 阻塞

    我正在调用 Process Start 但它会阻止当前线程 pInfo new ProcessStartInfo C Windows notepad exe Start process mProcess new Process mProce
  • ASP.NET MVC 6 (ASP.NET 5) 中的 Application_PreSendRequestHeaders 和 Application_BeginRequest

    如何在 ASP NET 5 MVC6 中使用这些方法 在 MVC5 中 我在 Global asax 中使用了它 现在呢 也许是入门班 protected void Application PreSendRequestHeaders obj

随机推荐

  • Java GUI 中的旋转方形面板

    我想知道是否可以实现一个方形但旋转 90 度的 GUI 面板 可能是 JPanel 显然 将有一个包含此面板的顶级容器 并且从视觉上看 主面板就是其中的旋转方形面板 更具体地说 我会将一个面板 称为 A 分成 4 个相等的方形子面板 并用
  • 智能手机网页设计 - 像素大小

    我需要有人帮助澄清我对高密度屏幕新手机像素大小的理解 从那时起 它就给我的网页设计带来了麻烦 我对智能手机的最初理解是像素尺寸大约为 480 x 320 这使得设计变得容易 因为像素仍然是相同的像素 然而 一些智能手机比这个多一倍 或更多
  • 如何“平滑”数据并计算线梯度?

    我正在从测量距离的设备读取数据 我的采样率很高 因此我可以测量距离 即速度 的较大变化 但这意味着 当速度较低时 设备会提供许多相同的测量结果 由于设备的粒度 这会产生 阶梯式 曲线 我需要做的是平滑曲线以计算速度 接下来我需要计算加速度
  • 如何使用Java代码将图像权限模式更改为777?

    我想使用Java代码为图像文件赋予权限模式值 777 我怎样才能用Java给出这个呢 因为我无法删除默认权限模式 664 的图像 您可以使用 exec 方法运行外部命令来执行 chmod Runtime getRuntime exec ch
  • 单个 Jekyll 网站中的多个博客

    有没有一种方法可以让一个 Jekyll 网站拥有多个博客 我目前想在一个网站上拥有两个博客 我是该页面的作者http www garron me blog multi blog site jekyll html 考虑到您需要单独的档案页面以
  • 从 ASP.NET 生成 Word 文档的最佳解决方案是什么? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 我想从我的 ASP NET 应用程序生成一个 Word 文档 目前我们显示 议程列表 其中包含议程信息和所有项目 主题 该页面需要能够在word中打
  • $(window).scroll(function() 在 Firefox 上不起作用?

    为了像 facebook 或 twitter 在其网站上那样加载页面 向下滚动 我用 jquery 尝试过 window scroll function if window scrollTop document height window
  • 传输编码:Windows Phone 中的分块

    我有一个带有 Transfer Encoding chunked 的服务器响应 HTTP 1 1 200 OK Server nginx 1 2 1 Date Mon 18 Feb 2013 08 22 49 GMT Content Typ
  • 如何合并两个不同的 Git 存储库?

    我有两个 Github 存储库 一个存储库位于远程服务器上 另一个存储库位于本地服务器上 它们都有不同文件和文件夹的不同提交历史记录 现在我想合并它们 以便我可以将它们作为一个存储库放在远程服务器上 请帮忙 我寻找了各种解决方案 建议如下
  • JS Promise - 立即从返回 Promise 的函数中检索一些数据

    谁能推荐一种从返回 Promise 的函数中立即检索数据的模式 我的 简化的 示例是 AJAX 预加载器 loadPage index html then displayPage 如果这是下载一个大页面 我希望能够检查正在发生的情况 并可能
  • 有没有办法确定理想的线程数? [复制]

    这个问题在这里已经有答案了 我正在做一个网络爬虫并使用线程来下载页面 我的程序性能的第一个限制因素是带宽 我永远无法下载它可以获得的更多页面 第二件事是我感兴趣的 我使用线程同时下载许多页面 但是当我创建更多线程时 会发生更多的处理器共享
  • R Dataframe 中的级别

    我从 csv 文件导入数据 并附加数据集 我的问题 一个变量是整数形式 有 295 个级别 我需要使用这个变量来创建其他变量 但我不知道如何处理这些级别 这些是什么 我该如何处理它们 当您使用 read table 或 read csv 您
  • 是否可以将动态程序集保存到磁盘?

    最近买了阿延德的书在 Boo 中构建 DSL 购买它 阅读它 太棒了 但是我遇到了一个实现问题 我想看看生成的代码是什么样的 我通常会使用反射器来查看代码 但在这种情况下 程序集是动态的并且仅在内存中 有没有办法将动态程序集保存到磁盘以便我
  • 覆盖路由器并向特定路由添加参数(在使用路径/url 之前)

    我会使用一个简单的管理路由系统 例如现在我有这条路线 welcome ANY ANY ANY acmedemo example index ANY ANY ANY acme demos acmedemo example edit ANY A
  • 如何使用证书而不是密码进行身份验证?

    我正在构建一个小型 C MVC5 应用程序 并准备向其中添加用户安全模块 之前我只是创建了一个会话变量来测试角色 但是 我的安全需求不适合我见过的任何预构建的安全模块 即 SimpleMembership 等 总结一下我的情况和需求 没有密
  • Yii2 DetailView:使用函数的属性值[重复]

    这个问题在这里已经有答案了 当我使用函数获取属性值时出现错误 并且使用 Gridview 可以正常工作 我做错了什么
  • 解决部分链接中的相对重定位

    我注意到使用 r看来 进行部分链接实际上并不能解决任何重定位问题 即使它们可以通过相对寻址来解决 例如 考虑f o and g o with f o含有f 哪个调用g within g o 链接之前 拆卸和重定位均符合预期 部分链接到新文件
  • Python 之禅“显式优于隐式”

    我试图理解 隐式 和 显式 在 Python 上下文中的真正含义 a my understanding is that this is implicit if not a print list is empty my understandi
  • 如何让abap程序暂停?

    出于测试目的 我需要我的 ABAP 程序等待几秒钟 如何才能做到这一点 2个解决方案 1 要么使用等待 秒 WAIT UP TO 42 SECONDS WAIT UP TO 0 5 SECONDS decimals are possible
  • C++0x:在 std::map 中存储任何类型的 std::function

    我试图在地图中存储一组 std function 在 GCC 4 5 下 我想要得到两种东西 存储已传递参数的函数 那么你就拥有了 调用 f 存储不带参数的函数 那么你必须打电话 F 我想我通过类 Command 和 Manager 实现了