0

I am looking to retrieving data members of a class without knowing the name of them. So going through a loop and finding a string and converting that string to a type. So then i know the type and can do something like:

std::cout << string_name_type << class:name_type << "\n";
//                 ^
//                 |
//            Found by loop and can ouput name of
//            Data member inside struct/class

I know that c++ does not have reflection but there is a library supplied by boost which has a tiny bit of reflection:

boost.org/doc/libs/master/doc/html/boost_pfr.html

This solves part of the problem: getting a data member from a struct like this:

#include <iostream>
#include <string>

#include "boost/pfr.hpp"

struct some_person {
    std::string name;
    unsigned birth_year;
};

int main() {
    some_person val{"Edgar Allan Poe", 1809};

    std::cout << boost::pfr::get<0>(val)                // No macro!
        << " was born in " << boost::pfr::get<1>(val);  // Works with any aggregate initializables!

    std::cout << boost::pfr::io(val);                   // Outputs: {"Edgar Allan Poe", 1809}
}

But I cannot output the type.

I tried a loop that just tries to find a type. But it only worked for three members or so and they had to be three characters.

I implemented it like this (from boost.org website):

`    #include<vector>

    std::vector<char> {'a', 'b', 'c', ...};

    struct c
    {
      int xyz;
    };

    c Class{};
    for(int i = 0; i < alphabet.size(); i++)
    {
     for(int j = 0; j < alphabet.size(); i++)
     {
      for(int k = 0; k < alphabet.size(); i++)
      {
          if(class::(alphabet[i] + alphabet[j] + alphabet[k]))
          {
          return Class::(alphabet[i] + alphabet[j] + alphabet[k]);
          }
      }
     }
    }`

But this obviously does not work. The problem that I was running into was converting a string into a data members type. Then I tried that the elements had to be one character long but that would obviously not work either:

`    for(int i = 0; i < alphabet.size(); i++)
    {
      if(class::alphabet[i])
    {
    return class::alphabet[i]
    }
    }`

I was expecting just a way to get a data member of a type, but i dont know the name of that data member.

I would like it to be like:

`   #include <iostream>  // std::cout 
    #include <string>    // std::string #include <vector>    // std::vector 
    std::vector<char> alpha{'a', 'b', 'c', 'd', 'e', 'f', 'g',
                            'h', 'i', 'j', 'k', 'l', 'm', 'n',
                            'o', 'p','q', 'r', 's', 't', 'u', 
                            'v', 'w', 'x', 'y', 'x'}; 
    struct NAME_TYPE 
    {
     // ... Or could be compiler generated    
    };
     [[nodiscard]] auto retrieve_name_from_class(auto& class_, std::string s)
     {
     NAME_TYPE* name =     to_name(s); return class_::name; 
     }
     struct X { // some_datamembers. int xyz; }
     int main() { X class_name; for (int i = 0; i < alpha.size(); i++)
     {
     // lots of loops; keeps looping till finds and name in the class
     if (alpha[a] + alpha[b] + alpha[c]... and so on)
     {
     std::string name = alpha[a] + alpha[b] + alpha[c]... extra; 
     auto x = retrieve_name_from_class(class_name, name) // x is the data member from the type 
      }
     }
    } `

So, I know of reflection and that you can get a type out of an object but I want to get a name that I don't know the name of the data member in object.

In one of Herb Sutter's talks at CppCon, one of the questions was something like "when are we getting a standard print, because we are now able to find data members of an object". So what i mean by that is: (a very rough sketch)

`    auto print(auto& x) // accepts a struct and prints it's data members 
     {
     print_helper(x::members);
     } `

So,

  • Is this already possible, e.g. with libraries?
  • Is reflection my answer?
  • If it is not possible, will it be soon?
  • I would advise to have a look at this https://www.boost.org/doc/libs/master/doc/html/boost_pfr.html Obviously it has quite a lot of limitations, but to my knowledge this is the most advance compile time reflection lib in C++ – Dmitry Oct 28 '22 at 16:29
  • @Dmitry Ok, thanks I will have a look. – Robert Shepherd Oct 28 '22 at 16:33
  • >Will it be soon? If we're super lucky, we may get basic reflection in the next C++ release (C++26), but I wouldn't hold my breath – AndyG Oct 28 '22 at 16:34
  • 1
    C++ does not work this way. There is no reflection in C++, of any kind. Trying to randomly guess syntax that results in reflection will always fail, and always end in tears. – Sam Varshavchik Oct 28 '22 at 16:35
  • Qt provides some functionality of extracting metadata of a class. Not sure, if you can make it work on this level, but something like Qt's moc is probably as close as you'll get. Qt does add a custom processing step analyzing a header file and generating a cpp file containing functionality for providing this kind of info... – fabian Oct 28 '22 at 16:42
  • If you *really* need this capability, then use `std::map`. This will allow you to waste time converting a member name to the member location. The `map` will need to be constructed for each instance, because instances can be created anywhere and members are in the instance. – Thomas Matthews Oct 28 '22 at 17:56

0 Answers0