Search code examples
c++arraysstructpointer-to-member

Dynamic member pointer array


Is it possible to create a dynamic array to save the names of each variable in a structure?

typedef struct dataSave {
    uint8_t nb;
    bool state;
    uint16_t dataIRArray[512];
} dataSave_t;

dataSave_t mysave;

template <typename T>
struct config_t {
    auto T::*var;
    char* name;
};

const config_t<dataSave_t> config[] = {
    {&dataSave_t::nb, "nb"},
    {&dataSave_t::state, "state"},
    {&dataSave_t::dataIRArray, "dataIRArray"}
};

The types of the structure's variables are different, and always generate an error:

error: non-static data member declared with placeholder 'auto'

I need to create something similar to dynamically going through a JSON and converting the JSON data just by adding it to the config list.


Solution

  • I guess you want something like this:

      template <typename owner>
      struct desc_base
      {
          virtual ~desc_base() = default;
          virtual std::string to_string(const owner&) = 0;
          virtual void from_string(owner&, std::string_view) = 0;
          const std::string name;
          desc_base(std::string_view name) : name(name) {}
      };
      
      template <typename owner, typename member>
      struct desc : desc_base<owner>
      {
          member owner::*ptr;
          std::string to_string(const owner& o) override { return my_to_string(o.*ptr); }
          void from_string(owner& o, std::string_view s) override { my_from_string(s, o.*ptr); }
          desc (member owner::*ptr, std::string_view name) : desc_base<owner>(name), ptr(ptr) {}
      };
      
      template <typename owner, typename member>
      std::unique_ptr<desc<owner, member>>
      make_desc(member owner::*ptr, std::string_view name) { return std::make_unique<desc<owner, member>>(ptr, name); }
      
      const std::unique_ptr<desc_base<dataSave_t>> config[] {
          make_desc(&dataSave_t::nb, "nb"),
          make_desc(&dataSave_t::state, "state"),
          make_desc(&dataSave_t::dataIRArray, "dataIRAArray")
      };
    

    This uses basic polymorphism technique to store an array of (smart pointers to) base class objects, where all the real work being done by the derived objects via virtual functions. Real work in this case being from_string and to_string. You can replace them with functions doing whatever real work you need to do, or just define my_to_string and my_from_string.