c++ - 为任务管理器封装成员函数指针的好方法

标签 c++ c++11 templates

我想在模板类 task 中存储一个成员函数指针和一个相关的对象指针。然后我想做一个数组,在scheduler类中调用这些成员函数。

但是,如果我将此类 task 保存在一个数组中,它们都需要具有相同的模板类型。这个障碍使得在任务类中保存对象指针变得毫无用处。

现在,我想知道是否有一种聪明的方法可以在相关的调度程序类中保护一组这样的对。如果我使用 std::tuple,我无法在运行时遍历容器,或者至少不能以一种非常可读的方式进行迭代。 有没有解决方案,我不需要调度程序类的模板?

template <class Obj>
struct task {    
    typedef void (Obj::*task_fn_t)();
    Obj*        obj_ptr;  // object referring
    task_fn_t   function; // member function
};

template <class Obj>
class scheduler {
    task <Obj> *_tasks; // problem :(
};

最佳答案

使用 std::function<void()> .

它几乎可以存储任何可以用 () 调用的东西.从逻辑上讲,一个 Obj*/成员函数指针合格(有一点包装)。

std::function<void()> f = [obj_ptr]{ obj_ptr->some_member_function(); };

std::function<Sig>是一个多态值类型。它存储(按值)任何可以以与 Sig 兼容的方式调用的东西。 .在你的例子中,你想用零参数调用一些东西并丢弃它的返回值。这与 void() 兼容签名。

对于像成员指针和对象指针这样的小对象,它会在没有任何堆分配的情况下执行此操作。

在大多数情况下,避免动态分配 std::function .

template<class..Args>
class scheduler {
  task = std::function<void(Args...)>;
  std::vector<task> tasks;
public:
  void add_task( task t ) { tasks.push_back(std::move(t)); }
  void operator()(Args...args) const {
    for (auto&& t:tasks)
      t(args...);
  }
};

这不会让您删除任务。我们可以添加该功能:

template<class Key, class..Args>
class scheduler {
  task = std::function<void(Args...)>;
  std::map<Key, task> tasks;
public:
  void add_task( Key const& k, task t ) {
    tasks[k] = std::move(t);
  }
  void remove_task( Key const& k ) {
    tasks.erase(k);
  }
  void operator()(Args...args) const {
    for (auto&& t:tasks)
      (t.second)(args...);
  }
};

现在您可以使用 key 添加任务,并在您不想让它们运行时删除它们。 (请注意,它们将按 key 的顺序运行)。

scheduler<std::string> bob;

bob.add_task( "hello", []{std::cout << "hello\n";} );
bob.add_task( "world", []{std::cout << "world\n";} );

bob(); // runs both tasks

bob.remove_task( "world" );

bob(); // runs only the "hello" task

关于c++ - 为任务管理器封装成员函数指针的好方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48754476/

相关文章:

c++ - 机器精度以及 double 类型的最大值和最小值

c++ - 在静态构造函数调用的 operator new 中访问 std::map

c++ - 为什么序列运算算法的谓词是通过拷贝传递的?

c++ - 在分配器中使用 new 和 *alloc 函数时有区别吗?

c++ - 未知的缺失库; -lGraf3d、-lPostscript 和 -lPhysics

c++ - 如何在本地重新定义 boost::shared_ptr?

c++ - LLVM IR 是否包含内置函数的代码

c++ - 假设从 gcc 上的重载函数强制转换为类型 xxx 时出错

c++ - 模板化静态成员函数指针初始化

html - 如何在 AngularJS 中为 ngInclude 指令指定模型?