В моем эпическом стремлении заставить C ++ делать то, чего не следует, я пытаюсь собрать класс, сгенерированный во время компиляции.
На основе определения препроцессора, например (грубая концепция)
CLASS_BEGIN(Name)
RECORD(xyz)
RECORD(abc)
RECORD_GROUP(GroupName)
RECORD_GROUP_RECORD(foo)
RECORD_GROUP_RECORD(bar)
END_RECORDGROUP
END_CLASS
Хотя я совершенно уверен, что сгенерирую класс, который считывает данные из файловой системы, используя такую структуру (возможно, даже делая это с помощью шаблонного метапрограммирования), я не вижу, как можно сгенерировать обе функции для доступа к данные и функция для чтения данных.
Я бы хотел получить класс вроде этого
class Name{
public:
xyz_type getxyz();
void setxyz(xyz_type v);
//etc
list<group_type> getGroupName();
//etc
void readData(filesystem){
//read xyz
//read abc
//etc
}
};
Кто-нибудь знает, если это вообще возможно?
- РЕДАКТИРОВАТЬ -
Чтобы уточнить предполагаемое использование для этого. У меня есть файлы в стандартном формате, который я хочу прочитать. Формат уже определен, поэтому он не подлежит изменению. Каждый файл может содержать любое количество записей, каждая из которых может содержать любое количество вложенных записей.
Каждый из многочисленных типов записей содержит различный набор вложенных записей, но они могут быть определены. Так, например, запись карты высот должна содержать карту высот, но необязательно может содержать нормали.
Итак, я бы хотел определить запись для этого следующим образом:
CLASS_BEGIN(Heightmap)
RECORD(VHDT, Heightmap, std::string) //Subrecord Name, Readable Name, Type
RECORD_OPTIONAL(VNML, Normals, std::string)
END_CLASS
Для которого я хотел бы вывести что-то с функциональностью класса, подобного этому:
class Heightmap{
public:
std::string getHeightmap(){
return mHeightmap->get<std::string>();
}
void setHeightmap(std::string v){
mHeight->set<std::string>(v);
}
bool hasNormal(){
return mNormal != 0;
}
//getter and setter functions for normals go here
private:
void read(Record* r){
mHeightmap = r->getFirst(VHDT);
mNormal = r->getFirst(VNML);
}
SubRecord* mHeightmap, mNormal;
}
У меня проблема в том, что мне нужно каждое определение препроцессора дважды. Один раз для определения определения функции в классе и один раз для создания функции чтения. Поскольку препроцессор является чисто функциональным, я не могу поместить данные в очередь и сгенерировать класс по определению END_CLASS marco.
Я не вижу пути решения этой проблемы, но мне было интересно, если бы кто-нибудь, кто лучше понимает C ++, сделал это.