任何结构接口

Any structure interface

本文关键字:接口 结构 任何      更新时间:2023-10-16

请给我一些有关此事的线索。预先感谢您,对不起,如果我的解释似乎有些混乱。

假设我有一些结构

struct Some
{
  DataTypeA a;
  DataTypeB b;
  ...etc.
};

我有这个接口:

class AnyStruct
{
public:
  using Variant = boost::variant<boost::blank, DataTypeA, DataTypeB, ...etc.>;
  using StringArr = std::vector<std::string>;
  virtual StringArr fieldNames() = 0;
  virtual Variant getValue(const std::string & fieldName) = 0;
};

futher我想实现此界面,以便有可能使用这样的字符串名称访问某些字段:

class SomeStruct : public AnyStruct
{
  Some m_some;
public:
  SomeStruct(const Some & some);
  /**
   * Function fieldNames returns vector {"a", "b", ...etc.}. Please, see the Some 
   * structure definition above.
   */
  virtual StringArr fieldNames();
  /**
   * 1. Function getValue with parameter "a" returns m_some.a wrapped in boost::variant
   * 2. Function getValue with parameter "b" returns m_some.b wrapped in boost::variant
   * ...etc.
   */
  virtual Variant getValue(const std::string & fieldName);
};

可能有一些优雅的解决方案或设计模式吗?我将非常感谢任何建议。

upd1:可能是可以使用宏观的。

写下这样的宏:

#define FIELDS( TOK ) 
  TOK(a), TOK(b), TOK(c), TOK(d)

列出了您要反思的所有变量。在您的CPP文件中,这是因为谁想揭露这个丑陋的?

使用:

#define STR2(X) #X
#define STR(X) STR2(X)
#define TOK_NAME(X) STR(X)

StringArr SomeStruct::fieldNames() {
  static char const*const names[] = {
    FIELDS(TOK_NAME)
  };
  return { std::begin(names), std::end(names) };
}
#define TOK_GET_MAP(X) 
  { STR(X), +[](SomeStruct* ptr)->AnyStruct{ return ptr->m_some.X; } }
Variant SomeStruct::getValue(const std::string& fieldName) {
  using get_map = std::map< std::string, AnyStruct(*)(SomeStruct*) >;
  static const get_map table = {
    FIELDS(TOK_GET_MAP)
  };
  auto it = get_map.find(fieldName);
  if (it != get_map.end()) return it->second(this);
  return boost::blank;
}

或各种。