【问题标题】:Packing an object, its method to call and arguments to call it with into a single object for invoking it later将一个对象、它的调用方法和调用它的参数打包到一个对象中,以便以后调用它
【发布时间】:2013-08-14 20:37:57
【问题描述】:

是否有可能使用 C++ 11 或 Boost 创建一个存储对象指针(实例)、方法指针和一些参数的对象,并且以后可以使用这些参数调用此方法?我的意思是 - 如何仅使用 std 或 Boost 模板来做到这一点?我很确定这是可能的,但不知道最好的方法是什么。

真正的问题是:是否可以在同一个容器中存储多个引用不同方法(具有不同签名)的此类对象?

【问题讨论】:

  • Is it possible, with C++ 11 or Boost, to create an object that ... 是的。 std::bind, boost::bind.
  • Is it in any way possible to store several such objects that refer to different methods (with diferent signatures) in the same container 不,不是真的。你为什么要这样做?
  • @LightnessRacesinOrbit:在我的具体情况下,它将允许非常方便的线程间调用机制。在工作线程中创建调用,在 UI 线程中调用,无需关心签名。
  • 哦,如果你预先绑定了所有参数,那很好。因为生成的仿函数将有 zero 参数和 void 返回类型;被调用的 actual 函数是否有参数并不重要,因为您已经绑定了它们。是的,这是一种常见的方法。
  • @LightnessRacesinOrbit:太好了,这就是我缺少的部分!谢谢。

标签: c++ boost


【解决方案1】:

这是std::bindstd::function 的经典用例:

#include <functional>
#include <vector>

using namespace std::placeholders;   // for _1, _2, ...

std::vector<std::function<int(double, char)>> v;

Foo x;
Bar y;

v.emplace_back(std::bind(&Foo::f, &x, _1, _2));         // int Foo::f(double, char)
v.emplace_back(std::bind(&Bar::g, &y, _2, true, _1));   // int Bar::g(char, bool, double)
v.emplace_bacK(some_free_function);                     // int some_free_function(double, char)

使用方法:

for (auto & f : v) { sum += f(1.5, 'a'); }

【讨论】:

  • 您的 Foo::f 示例略有损坏(参数数量错误)。
  • @LightnessRacesinOrbit:呃,我一直希望这能奏效:-S
  • 你的意思是占位符在没有给出时自动绑定?
  • @LightnessRacesinOrbit:是的。感觉像是应该明显起作用的东西……它可能与boost::bind 一起使用吗?我总觉得我在哪里见过。
  • 不,据我所知。 (就我的记忆而言,也不是根据我的经验。)
【解决方案2】:

查看 C++11 提供的 std::bind。它完全符合您的要求。你甚至不需要为此提升。例如:

class C
{
public:
  void Foo(int i);
}

C c;

// Create a function object to represent c.Foo(5)
std::function<void(void)> callLater=std::bind(&C::Foo,std::ref(c),5);

// Then later when you want to call c.Foo(5), you do:
callLater();

【讨论】:

  • 但是我可以在同一个容器中存储不同的函数对象吗?
  • @VioletGiraffe 生成的对象可以轻松存储在std::function 中。如果函数对象都具有相同的签名,您可以为它们创建一个容器,例如,std::vector&lt;std::function&lt;void()&gt;&gt;
  • .. 但如果他们不这样做。
  • 不能轻易的将不同类型的函数对象存储在同一个容器中。此外,您不能相互比较函数对象,除非测试它们是否都是空的。
  • 啊,是的,OP 正在绑定 all 参数,所以这里的关键是表达式 callLater() 确实是所需要的(它具有同构存储的必然结果) . +1
猜你喜欢
  • 1970-01-01
  • 2012-12-28
  • 1970-01-01
  • 1970-01-01
  • 2017-05-20
  • 1970-01-01
  • 1970-01-01
  • 2017-03-30
  • 1970-01-01
相关资源
最近更新 更多