4

我有一个类型定义:

typedef S32(iMyDataClass1::*getDataFunction_t)(void);

和一个类型:

struct functionMap_t {
    std::vector<getDataFunction_t> pDataFunctionTable;
    struct dataRequestor_t dataRequestor;
};

然后我有一个成员变量:

functionMap_t FnMap1;

然后我在成员初始化器列表中设置:

myClass::myClass() : FnMap1({ 
 {
     &iMyDataClass1::getData1,
     &iMyDataClass1::getData2,
     &iMyDataClass1::getData3
   },
   dataRequestor1
 })

然后我在构造函数中使用它:

addNewFnMap(FnMap1);

这一切都很好。不幸的是,它对于指向不同类的函数指针是不可扩展的,因为getDataFunction_t它绑定到了iMyDataClass1

我尝试使用模板,但遇到了我无法解决的问题。现在我正在尝试使用std::function,这意味着我将原始 typedef 更改为(我认为):

typedef std::function<S32(void)> getDataFunction_t;

在这种情况下设置我的初始化列表的正确方法是什么?我在这里用std::bind吗?

更新:这是我对新初始化列表的尝试。我不知道这是否正确,但这是我在发布这个问题之前所拥有的:

{ 
  {
    (std::bind(&iMyDataClass1::getData1, functionToFetchCorrectObject())),
    (std::bind(&iMyDataClass1::getData2, functionToFetchCorrectObject())),
    (std::bind(&iMyDataClass1::getData3, functionToFetchCorrectObject()))
  },
  PGN65370
}
4

2 回答 2

3

您可以使用 lambda 表达式。但是,如果您想将签名保留为std::function<S32(void)>,则需要捕获您的对象。

myClass::myClass() : FnMap1({
  {
     [this](){ return getData1(); },
     [this](){ return getData2(); },
     [this](){ return getData3(); },
  },
  dataRequestor1
})

如果您不想这样做,您可以更改签名以将this指针作为参数传递给您的回调。但正如 Barry 在评论中指出的那样,这不允许您将不同类的回调放入同一个vector. 您可以reinterpret_cast在 lambda 中使用指针,但除了丑陋和危险之外,调用者如何知道要传递什么指针?

于 2015-05-11T21:26:37.810 回答
2

如果您希望它与不同的类一起使用,您可以简单地使用您想要的任何签名存储可调用对象:

struct functionMap_t {
  std::vector<std::function<S32(void)>> pDataFunctionTable;
  struct dataRequestor_t dataRequestor;
};

接下来,我可能会为您的班级提供更高阶的函数,这些函数返回具有正确签名的 std::functions 。

std::function<S32(void)> iMyDataClass1::getData1Getter() {
  auto f = [this] () {return this->getData1()};
  return f;
}

现在你可以很简单地初始化:

iMyDataClass1 o;
...

FnMap1({o.getData1Getter(), ..., dataRequestor1});

这段代码没有经过仔细检查,我确信它包含语法错误。但它应该给你它的要点。主要思想是:如果您想使用可能附加或不附加到特定对象的函数,那么您需要使用函数(实际上,闭包本身)。以这种方式使用函数会激发使用高阶函数的设计,从一个上下文返回函数并将它们传递给另一个上下文。

编辑:我最近与某人就 C++11 中的观察者模式进行了一些设计对话。我建议做一些与此非常相似的事情,避免使用多态性,保持通用性和解耦,并避免污染继承层次结构非常好。

于 2015-05-11T21:47:17.603 回答