Ich beginne mit Boost.Hana und frage mich, ob es einen Weg gibt, um wieder in ein Struct zu deserialisieren, das Boost.Hana bekannt ist. Ich weiß, es ist ziemlich einfach, ein solches Struct in eine JSON-Zeichenfolge zu serialisieren, aber ich habe keine Information darüber gefunden. Ist es derzeit einfach nicht möglich, Daten mit Boost.Hana zu deserialisieren oder fehlt mir etwas?Ist es möglich, mit Boost.Hana zu deserialisieren?
Antwort
Hana ist eine Metaprogrammierungsbibliothek. Es bietet Tools, die verwendet werden können, um komplexere Funktionen wie Serialisierung zu bauen, aber es bietet keine solche Funktionalität selbst. Es ist einfach nicht der Umfang dieser Bibliothek. Auch in Bezug auf Ihren speziellen Anwendungsfall; Parsing ist kein einfaches Problem und andere Bibliotheken versuchen, Boost.Spirit bereits zu lösen.
Das skizzierte ich skizzierte ein Beispiel der Verwendung von Hana zum Deserialisieren von JSON. Das Ergebnis ist weder effizient noch robust, aber es sollte reichen, um Ihnen einen Einblick zu geben, wie Hana verwendet werden könnte, um etwas Besseres zu erreichen. Solving dieses Problem korrekt würde erfordern, eine Parser-Kombinator-Bibliothek à-la Boost.Spirit implementieren, die ich hier nicht tun werde. Hier gehen Sie:
template <typename T>
std::enable_if_t<std::is_same<T, int>::value,
T> from_json(std::istream& in) {
T result;
in >> result;
return result;
}
template <typename T>
std::enable_if_t<std::is_same<T, std::string>::value,
T> from_json(std::istream& in) {
char quote;
in >> quote;
T result;
char c;
while (in.get(c) && c != '"') {
result += c;
}
return result;
}
template <typename T>
std::enable_if_t<hana::Struct<T>::value,
T> from_json(std::istream& in) {
T result;
char brace;
in >> brace;
hana::for_each(hana::keys(result), [&](auto key) {
in.ignore(std::numeric_limits<std::streamsize>::max(), ':');
auto& member = hana::at_key(result, key);
using Member = std::remove_reference_t<decltype(member)>;
member = from_json<Member>(in);
});
in >> brace;
return result;
}
template <typename Xs>
std::enable_if_t<hana::Sequence<Xs>::value,
Xs> from_json(std::istream& in) {
Xs result;
char bracket;
in >> bracket;
hana::length(result).times.with_index([&](auto i) {
if (i != 0u) {
char comma;
in >> comma;
}
auto& element = hana::at(result, i);
using Element = std::remove_reference_t<decltype(element)>;
element = from_json<Element>(in);
});
in >> bracket;
return result;
}
Und dann kann man es verwenden, wie
struct Car {
BOOST_HANA_DEFINE_STRUCT(Car,
(std::string, brand),
(std::string, model)
);
};
struct Person {
BOOST_HANA_DEFINE_STRUCT(Person,
(std::string, name),
(std::string, last_name),
(int, age)
);
};
int main() {
std::istringstream json(R"EOS(
[
{
"name": "John",
"last_name": "Doe",
"age": 30
},
{
"brand": "BMW",
"model": "Z3"
},
{
"brand": "Audi",
"model": "A4"
}
]
)EOS");
auto actual = from_json<hana::tuple<Person, Car, Car>>(json);
auto expected = hana::make_tuple(Person{"John", "Doe", 30},
Car{"BMW", "Z3"},
Car{"Audi", "A4"});
assert(actual == expected);
}
Das vollständige Beispiel ist here verfügbar.
Die boost :: hana json Encoder Compelete nicht (es ist nicht zitiert zum Beispiel entweicht): http://www.boost.org/doc/libs/1_61_0/libs/hana/doc/html/index.html#tutorial-introspection-json
Um Deserialisieren ichboost :: spirit :: x3 verwenden würde: http://ciere.com/cppnow15/x3_docs/index.html
Sie haben einen Jsons Deserializer Beispiel: https://github.com/cierelabs/json_spirit
- 1. Ist es möglich, in ein ExpandoObject (oder Dictionary) mit stark typisierten Membern zu deserialisieren, wo es möglich ist?
- 2. Ist es möglich, ein "ISODate" -Feld von MongoDB zu einem JToken (C#) zu deserialisieren?
- 3. Ist es möglich, ein Objekt in C# zu deserialisieren, das in C++ MFC binär serialisiert wurde?
- 4. Ist es möglich, Reflexion mit LINQ zu Entität zu verwenden?
- 5. Ist es möglich, mit Svg wie mit Glyphicon zu handeln?
- 6. Ist es möglich, alle Funktionen zu verschachteln?
- 7. Ist es möglich, ein Icon zu verschieben?
- 8. Ist es möglich, die Zeichencodierung zu "schnüffeln"?
- 9. Ist es möglich, Portable VM zu erstellen?
- 10. Ist es möglich, drawableLeft programmgesteuert zu setzen?
- 11. Ist es möglich, Cookies zu sichern?
- 12. Ist es möglich, getopt zu wiederholen
- 13. Ist es möglich, Rowspans zu wechseln?
- 14. Ist es möglich, Alarme zu bearbeiten?
- 15. ImageMagick: Ist es möglich, "Schnittmarken" zu entfernen?
- 16. Ist es möglich, ein Einlaufen zu erkennen?
- 17. Ist es möglich, transparente Leinwand zu erstellen
- 18. Ist es möglich, Syntax wie -()() zu schreiben?
- 19. Ist es möglich, einen Datenbanktransaktionsparameter zu verfälschen?
- 20. Ist es möglich, Inline-Vorlagen zu verwenden?
- 21. createjs: Ist es möglich, Text zu rechtfertigen?
- 22. Ist es möglich, ASP.NET-Seiten zu crawlen?
- 23. Ist es möglich, PostGIS zu PipelineDB hinzuzufügen?
- 24. Ist es möglich, nbviewer lokal zu hosten?
- 25. Ist es möglich, einen Gradienten zu zeichnen?
- 26. Ist es möglich, CPU-Zyklen zu mieten?
- 27. Ist es möglich, einen ValueType zu klonen?
- 28. BlackBerry - ist es möglich, Markenanwendungen zu entwickeln?
- 29. Ist es möglich, Blöcke zu markieren?
- 30. Es ist möglich, SpeechRecognizer schneller zu machen?
Danke, Louis. Ich habe versucht, an Mitglieder zu schreiben, indem ich hana :: for_each (hana :: members (result), [] ...) nutzlos benutzte. Sie haben eine erstaunliche Bibliothek erstellt! –