#include <iostream>
#include <string>
#include <tuple>
#include <vector>
#include <cstdlib>
struct FieldBase
{
// To enable dynamic_cast.
virtual void fb()
{
}
};
template <typename A, typename B>
struct Field : public FieldBase
{
Field(A B::* v) :
value(v)
{
}
A B::* value;
};
template <typename A>
struct MetaData
{
static std::vector<FieldBase> fields;
};
struct Test
{
unsigned int a;
std::string b;
};
template <>
struct MetaData<Test>
{
static const std::vector<FieldBase*> fields;
};
const std::vector<FieldBase*> MetaData<Test>::fields{ new Field<unsigned int, Test>(&Test::a), new Field<std::string, Test>(&Test::b) };
template <typename A>
void serialize(const A& object)
{
std::cout << typeid(A).name() << std::endl;
for (const FieldBase* field : MetaData<A>::fields)
{
const Field<unsigned int, A>* f1 = dynamic_cast<const Field<unsigned int, A>*>(field);
if (f1 != 0)
std::cout << object.*f1->value << std::endl;
const Field<std::string, A>* f2 = dynamic_cast<const Field<std::string, A>*>(field);
if (f2 != 0)
std::cout << object.*f2->value << std::endl;
}
}
int main()
{
Test test;
test.a = 2014;
test.b = "Hello";
serialize(test);
std::cin.sync();
std::cin.get();
return EXIT_SUCCESS;
}
Here is something I could think of. But I do not think this is the right approach at all.
What I would really like to do is examining the stored fields without any dynamic casts.
Would it be meaningful to store Fields in a tuple and then go through all the tuple elements? Although I am not sure how to access tuple elements when the index comes from a loop counter.
std::tuple<Field<unsigned int, Test>, Field<std::string, Test>>
How does one iterate over that tuple when its size may vary?