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?