Рефлексия в плюсах - обойти все поля структуры в рантайм?
Хочется объявить поля в структуре/классе так, что бы потом иметь возможность обойти их в рантайм/иметь возможность обращаться по имени в рантайм. Ограничения:
-
стандарт не свежее с++-17
-
всякие толстые сторонние либы а-ля буст не подходят
-
задание полей должно быть максимально простым, желательно что бы каждое поле упоминалось не больше одного раза.
-
необходимо иметь возможность довешивать к полям комментарии (можно статические) и потом иметь к ним доступ в рантайм.
Хочется че то такое:
struct A{
BEGIN(); // некий макрос
int PAR(x, 0, "число рыбов");
std::array<double, 2> PAR(y, {0., 0.}, "координаты главрыбы");
END();
};
но как это сделать фантазии не хватает (есть варианты, но они все ужасно костыльные).
Можно легко сделать что то вроде
struct A{
double x = 0;
std::array<double, 2> y = {0., 0.};
A(){ TABLE(x, "число рыбов")(y, "координаты главрыбы"); }
};
но нарушается п.3.
Можно на худой конец сделать
struct A{
int x = 0; ///< число рыбов
std::array<double, 2> y = {0., 0.}; ///< координаты главрыбы
};
и перед сборкой обрабатывать это питоньей утилитой, генерить хидер с какой то оберткой и его инклюдить, но выглядит несколько радикально…
Как бы такое сделать Ъ? annulen, fsb4000, monk, bugfixer
UPD. Решил чуть подробнее расписать зачем это нужно и что должно выйти в итоге. Есть приложение (HPC) в котором есть вычислительное ядро на плюсах. В ядре есть класс Model со 100500 параметров (входных и выходных содержащих результаты расчета) которые имеют значения по умолчанию, но нужно мочь их менять через конфиги/аргументы командной строки, куда то записывать (в json) и т.д. Если забиндить ядро в питон (через SWIG) то это все делается довольно легко, но такой биндинг не всегда возможен. Хочется иметь аналогичную функциональность на чистых C++. Т.е. в C++ я изначально пишу:
class Model{
...
double J = 1; ///< exchange integral
double T = 2; ///< temperature
double c = 0.1; ///< concentration
double dt = 1e-2; ///< time step
double t = 0; ///< time
...
void init();
void calc();
};
Пускач в питоне
model = Model()
config(model) # это функция из моей либы накатывающая параметры из командной строки
model.init()
while model.t<t_max: model.calc()
при запуске я могу писать что то вроде
./run.py T=4 dt=1e3
хочется мочь писать аналогичный пуска на плюсах.
Для этого необходимо и достаточно иметь в плюсах некую обертку для модели которая:
- может перечислить все параметры
- может вернуть значение любого параметра в виде строки
- может задать значение любого параметра из строки
- бонусом (то чего в питоне пока нет, но хочется и туда пробросить) - может вернуть комментарий к любому параметру