首页 > 解决方案 > 将字符串映射到类成员

问题描述

假设我有一个如下所示的类/结构:

struct A {
    uint32_t a;
    uint8_t  b;
    uint16_t c;
};

而且我有一组与 A 的每个成员相关联的字符串(可以是不同的整数类型,但不是非整数类型,例如字符串),例如

"field1" -> A::a
"field2" -> A::b
"field3" -> A::c

假设字符串和成员之间始终存在 1:1 映射。有没有一种优雅的方法可以使用 std::unordered_map 之类的东西将每个字符串映射到每个成员?我希望能够使用字符串作为键读取和写入每个字段,例如

A a {1,2,3};
mymap["field1"] = 4; // a.a = 4
mymap["field2"] = 5; // a.b = 5
auto c = mymap["field3"]; // c = a.c = 3

我正在使用 C++11/14 并且不能使用 boost。


有关此问题上下文的更多信息struct A问题中提到的是程序的设置。它们是硬件配置参数,我的软件程序用于模拟硬件行为。这些设置/配置是脚本生成的成员。正如我在问题中提到的,这些成员属于不同的整数类型。struct的。我们读/写这些struct成员,并且因为这些设置/配置的数量如此之多(几千),所以能够通过它们的名称访问它们会很方便。这就是我想将每个成员与字符串相关联的方式和原因。是下标还是函数访问对应的成员其实并不重要,但是字符串(设置的名称)和生成的就存在这样的1:1映射关系struct

标签: c++c++11c++14

解决方案


template<class V>
struct pseudo_ref_t {
  operator V()&& { return getter(); }
  void operator=(V v)&&{
    setter(std::move(v));
  }

  std::function<void(V)> setter;
  std::function<V()> getter;
};
template<class T, class V>
struct member_t {
  friend pseudo_ref_t<V> operator->*( T* t, member_t const& self ) {
    return {
      [&self, t](V in){ self.setter(*t, std::move(in)); },
      [&self, t]()->V{ return self.getter(*t); }
    };
  }
  friend V operator->*( T const* t, member_t const& self ) {
    return self.getter(*t);
  }
  std::function<void(T&, V)> setter;
  std::function<V(T const&)> getter;
};
template<class T, class V, class X>
member_t<T, V> make_member( X T::* mem_ptr ) {
  return {
    [mem_ptr](T& t, V in) {
      (t.*mem_ptr) = std::move(in);
    },
    [mem_ptr](T const& t)->V {
      return (t.*mem_ptr);
    }
  };
}

a可以类型擦除可隐式转换为/从 a 的member_t<A, uint32_t>任何成员。Auint32_t

它就像一个智能成员指针。


推荐阅读