c++ - 如何通过函数指针调用不同签名的C++函数

标签 c++ functor

我有一个 C++ 应用程序,其中 main() 实例化一个对象 MyApp,然后将该对象传递给 ReadConfig 函数。

ReadConfig 打开一个基于文本的文件,对其进行解析,然后调用适当的 MyApp 方法对其进行配置。

class MyApp
{
private:

public:
  void SetRate(uint16_t);
  void EnableLogging(bool);
  void SetAddress(uint32_t);
};

我正在努力使 ReadConfig 的维护变得容易,以便在将新的公共(public)方法添加到 MyApp 时,它可以像更新表一样简单。我想出了以下解决方案,但我不喜欢它。由于必须确保我将 0 放在正确的位置,因此很难维护。

下面是我能够解决的问题的示例。任何使这更好的建议将不胜感激。请注意,我在嵌入式系统中工作,因此我们使用的 C++ 编译器不支持 C++14 并且没有提升。我想避免使用任何 STL 库,以便自己了解执行此操作的机制。

这是我的:

enum ARGTYPE {TBOOL, TUINT16, TUINT32};

template<typename TOBJ, typename TARG>
struct TSetting
{
  void (TOBJ::*FSet)(TARG);
};

template<typename obj>
struct SETTINGFN
{
  const char                       *setting_name;
  ARGTYPE                          Targ;
  TSetting<obj,bool>               HBool;
  TSetting<obj,uint16_t>           HUint16;
  TSetting<obj,uint32_t>           HUint32;
};

SETTINGFN<MyApp> MyAppSettings[] =
{
  "logging"    ,TBOOL,       &MyApp::EnableLogging, 0,0,0
  ,"maxrate"   ,TUINT16,     0,0,0,&MyApp::SetRate
  ,"address"   ,TUINT32,     0, &MyApp::SetAddress, 0,0

};
unsigned int MyAppSettings_Count = sizeof(MyAppSettings) / sizeof(SETTINGFN<MyApp>);

然后,当我读取配置文件并对其进行解析时,我调用一个函数来处理通过函数指针调用实际 MyApp 函数。该函数如下:

bool AppSetting(MyApp &E, TObjnode &node)
{
  bool rval = false;

  for(unsigned int i=0; i<MyAppSettings_Count && !rval; i++)
  {
    if(node.GetName() == MyAppSettings[i].setting_name)
    {
      rval = true;

      switch(MyAppSettings[i].Targ)
      {
        case TBOOL:
          (E.*MyAppSettings[i].HBool.FSet)(node.GetValue().AsBool());
        break;

        case TUINT16:
          (E.*MyAppSettings[i].HUint16.FSet)(node.GetValue().Value());
        break;

        case TUINT32:
          (E.*MyAppSettings[i].HUint32.FSet)(node.GetValue().Value());
        break;
      }
    }
  }

  return(rval);
}

最佳答案

您设计中的棘手问题是不同的参数类型。

如果把参数抽象成一个结构体,那么函数就可以简化为一个固定的签名。

通过使用基础结构,签名变得更加通用:

struct Arguments_Base
{
};

void SetRate(Arguments_Base& ab);
void EnableLogging(Arguments_Base& ab);
void SetAddress(Arguments_Base& ab);

通过统一签名,函数指针函数对象可以在表或映射中使用,使搜索更容易。搜索引擎应该能够通用并依赖于数据的大小,以便只需要更改数据(例如表格),而不是搜索引擎。

每种类型的参数集都应该派生自 Arguments_Base 类。然后该函数可以dynamic_cast 基类引用。

另请参阅:工厂设计模式、访问者设计模式、双重 dispatch

关于c++ - 如何通过函数指针调用不同签名的C++函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42013909/

相关文章:

c++ - 简单、高效的弱指针,在释放目标内存时设置为 NULL

c++ - 如何从 QDataStream 中读取多个相同类型的序列化对象?

c++ - Bazel:本地访问附近的文件

c++ - 如何从 QProcess 获取错误代码?

c++ - 比较字符串c++的问题

haskell - 在具有多个类型类的自定义数据类型上使用仿函数/应用程序?

c++ - 在一个函数中嵌入不同的函数 : functor or lambda?

c++ - accumulate 的 Functor 有什么要求?

c++ - 有没有办法拥有更严格的泛型仿函数参数?

c++ - 如何在非模板类中存储仿函数?