циклом обойти их, чтобы сделать какие-то действия.
Код: Выделить всё
// нужен обход полей класса, объект класса должен быть копируемый и с move семантикой
// какой вариант с member pointer лучше по красоте, поддержке, скорости ....
// а может есть какой-нить третий ?
#include <string>
#include <unordered_map>
#include <iostream>
#include <functional>
struct Iface {
virtual void print() const = 0;
virtual ~Iface() {}
};
template <class T> struct Realize final : public Iface {
Realize(
const std::string & name
, const T & val = T()
) : name(name), val(val) {}
std::string name; // < исправлено - удалено const std::string name;
T val;
inline void print() const override {
std::cout << "name=" << name << " val=" << val << std::endl;
}
};
struct Usage {
#define VAR(name, default_value) m_##name(#name, default_value)
Usage() : VAR(Var1, 123), VAR(Var2, "test") {}
Realize<int> m_Var1;
Realize<std::string> m_Var2;
// 1 вариант
static const std::unordered_map<std::string, const Iface Usage::*> m_allVars1;
inline void print1() const {
for (const auto & each : m_allVars1) { (this->*(each.second)).print(); }
}
// 2 вариант
using getMember = const Iface & (* const)(const Usage &);
static const std::unordered_map<std::string, getMember> m_allVars2;
inline void print2() const {
for (const auto & each : m_allVars2) { each.second(*this).print(); }
}
};
// 1 вариант
const decltype(Usage::m_allVars1) Usage::m_allVars1 = {
// { "Var1", &Usage::m_Var1 } // error: could not convert ‘{&Usage::m_Var1}’ from ‘<brace-enclosed initializer list>’ to ‘const std::vector<Iface Usage::*>’
#define ELEMENT(name) { #name, reinterpret_cast<Iface Usage::*>(&Usage::m_##name) } // OK но так стремно
ELEMENT(Var1)
, ELEMENT(Var2)
};
// 2 вариант
const decltype(Usage::m_allVars2) Usage::m_allVars2 = {
#undef ELEMENT // )))
#define ELEMENT(name) { #name, [](const Usage &s) -> const Iface & {return s.m_##name;} }
ELEMENT(Var1)
, ELEMENT(Var2)
};
int main() {
Usage usage;
usage.print1();
usage.print2();
return 0;
}