繁体   English   中英

动态和静态地访问C ++结构中的成员

[英]Accessing members in a C++ struct both dynamically and statically

我想在C ++中有一个结构(或类似的东西),它将允许动态访问其成员。 它应该有一个通用的getter和setter,它们将成员名称作为字符串接收,并返回某种变体类型(例如boost::variant )。

我想它可以使用boost::fusion::map ,添加一个表示每个成员名称的字符串,并在字符串和getter或setter函数之间构建一个STL映射。 我不想重新发明轮子,所以我希望类似的东西已经存在。

你怎么看? 我的想法会奏效吗? 你知道其他方法来实现我的目标吗?

谢谢,哈该

fusion是一种方法,但为什么不将你的“字段”存储在由std::string键入的std::map ,其中有效负载是boost::variant ...

struct generic
{
std::map<std::string, boost::variant<foo, bar, bob, int, double> > _impl;
};

然后你可以在你的getter / setter中查找键...

哎呀,将variant包装在一个optional ,你可以选择字段!

一个更复杂的例子:

class foo
{
public:
  typedef boost::variant<int, double, float, string> f_t;
  typedef boost::optional<f_t&> return_value;
  typedef map<string, return_value> ref_map_t;

  foo() : f1(int()), f2(double()), f3(float()), f4(string()), f5(int()) 
  {
    // save the references..
    _refs["f1"] = return_value(f1);
    _refs["f2"] = return_value(f2);
    _refs["f3"] = return_value(f3);
    _refs["f4"] = return_value(f4);
    _refs["f5"] = return_value(f5);
  }

  int getf1() const { return boost::get<int>(f1); }
  double getf2() const { return boost::get<double>(f2); }
  float getf3() const { return boost::get<float>(f3); }
  string const& getf4() const { return boost::get<string>(f4); }
  int getf5() const { return boost::get<int>(f5); }

  // and setters..
  void setf1(int v) { f1 = v; }
  void setf2(double v) { f2 = v; }
  void setf3(float v) { f3 = v; }
  void setf4(std::string const& v) { f4 = v; }
  void setf5(int v) { f5 = v; }

  // key based
  return_value get(string const& key)
  {
    ref_map_t::iterator it = _refs.find(key);
    if (it != _refs.end())
      return it->second;
    return return_value();
  }

  template <typename VT>
  void set(string const& key, VT const& v)
  {
    ref_map_t::iterator it = _refs.find(key);
    if (it != _refs.end())
      *(it->second) = v;
  }

private:
  f_t f1;
  f_t f2;
  f_t f3;
  f_t f4;
  f_t f5;

  ref_map_t _refs;
};

int main(void)
{
  foo fancy;
  fancy.setf1(1);
  cout << "f1: " << fancy.getf1() << endl;

  fancy.set("f1", 10);
  cout << "f1: " << fancy.getf1() << endl;

  return 0;
}

您在C ++中要求反思 ,我认为这是不可用的。 你必须想出自己的东西。

我为此做的是一个boost :: cons-like类型列表,其中包含我的成员和某种描述。 然后,我通过“链式”函数调用将我的成员连续添加到“元信息”数据结构来构建此映射。 整个过程看起来非常类似于在boost.python中定义一个类。 如果你实际使用boost :: cons,它也应该作为boost.fusion中的一个序列,所以你可以很好地迭代你的数据。 也许您可以使用boost.fusion映射来获取运行时的log(n)访问时间,但看起来它们的大小是有限的,直到可变参数模板可用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM