El RareCpp Bibliothek sorgt für eine relativ einfache und intuitive Reflexion - alle Feld-/Typinformationen sind so konzipiert, dass sie entweder in Arrays verfügbar sind oder sich wie ein Array-Zugriff anfühlen. Es ist für C++17 geschrieben und arbeitet mit Visual Studios, g++ und Clang. Die Bibliothek ist eine reine Header-Bibliothek, d.h. Sie müssen nur "Reflect.h" in Ihr Projekt kopieren, um sie zu verwenden.
Reflektierte Strukturen oder Klassen benötigen das REFLECT-Makro, bei dem Sie den Namen der Klasse, die Sie reflektieren, und die Namen der Felder angeben.
class FuelTank {
public:
float capacity;
float currentLevel;
float tickMarks[2];
REFLECT(FuelTank, capacity, currentLevel, tickMarks)
};
Das ist alles, es ist kein zusätzlicher Code zur Einrichtung der Reflexion erforderlich. Optional können Sie Klassen- und Feldannotationen bereitstellen, um Superklassen zu durchlaufen oder zusätzliche Kompilierzeitinformationen zu einem Feld hinzuzufügen (z. B. Json::Ignore).
Das Durchlaufen von Feldern kann so einfach sein wie...
for ( size_t i=0; i<FuelTank::Class::TotalFields; i++ )
std::cout << FuelTank::Class::Fields[i].name << std::endl;
Sie können eine Objektinstanz in einer Schleife durchlaufen, um auf Feldwerte (die Sie lesen oder ändern können) und Feldtypinformationen zuzugreifen...
FuelTank::Class::ForEachField(fuelTank, [&](auto & field, auto & value) {
using Type = typename std::remove_reference<decltype(value)>::type;
std::cout << TypeToStr<Type>() << " " << field.name << ": " << value << std::endl;
});
A JSON-Bibliothek baut auf RandomAccessReflection auf, die automatisch geeignete JSON-Ausgabedarstellungen zum Lesen oder Schreiben identifiziert und rekursiv alle reflektierten Felder sowie Arrays und STL-Container durchlaufen kann.
struct MyOtherObject { int myOtherInt; REFLECT(MyOtherObject, myOtherInt) };
struct MyObject
{
int myInt;
std::string myString;
MyOtherObject myOtherObject;
std::vector<int> myIntCollection;
REFLECT(MyObject, myInt, myString, myOtherObject, myIntCollection)
};
int main()
{
MyObject myObject = {};
std::cout << "Enter MyObject:" << std::endl;
std::cin >> Json::in(myObject);
std::cout << std::endl << std::endl << "You entered:" << std::endl;
std::cout << Json::pretty(myObject);
}
Der obige Ablauf könnte so aussehen...
Enter MyObject:
{
"myInt": 1337, "myString": "stringy", "myIntCollection": [2,4,6],
"myOtherObject": {
"myOtherInt": 9001
}
}
You entered:
{
"myInt": 1337,
"myString": "stringy",
"myOtherObject": {
"myOtherInt": 9001
},
"myIntCollection": [ 2, 4, 6 ]
}
Siehe auch...
21 Stimmen
Pech gehabt, ohne Makros und andere Vorverarbeitungen geht es nicht, denn die erforderlichen Metadaten gibt es nicht es sei denn, Sie erstellen sie manuell mit Hilfe von Makro-Vorverarbeitungsmagie.
7 Stimmen
Die Informationen, die Sie von RTTI erhalten können, reichen jedoch nicht aus, um die meisten Dinge zu tun, für die Sie eigentlich eine Reflexion benötigen würden. Sie können zum Beispiel nicht über die Mitgliedsfunktionen einer Klasse iterieren.