Converting C++ class to JSON
JSON Spirit would allow you to do it like so:
Object addr_obj;
addr_obj.push_back( Pair( "house_number", 42 ) );
addr_obj.push_back( Pair( "road", "East Street" ) );
addr_obj.push_back( Pair( "town", "Newtown" ) );
ofstream os( "address.txt" );
os.write( addr_obj, os, pretty_print );
os.close();
Output:
{
"house_number" : 42,
"road" : "East Street",
"town" : "Newtown"
}
The json_map_demo.cpp would be a nice place to start, I suppose.
Any good C++ JSON library should do this and it is sad to see that they don't -- with the exception of ThorsSerializer and apparently Nosjob as mentioned in this question.
Of course, C++ does not have reflection like Java, so you have to explicitly annotate your types:
(copied from the ThorsSerializer documentation)
#include "ThorSerialize/JsonThor.h"
#include "ThorSerialize/SerUtil.h"
#include <map>
#include <vector>
#include <string>
#include <iostream>
class Example {
std::string string;
std::map<std::string, std::string> map;
std::vector<int> vector;
// Allow access to the class by the serialization library.
friend class ThorsAnvil::Serialize::Traits<Example>;
public:
Example(std::string const& s, std::map<std::string, std::string> const& m, std::vector<int> const& v)
: string(s), map(m), vector(v)
{}
};
// Define what members need to be serilizable
ThorsAnvil_MakeTrait(Example, string, map, vector);
Example Usage:
int main()
{
using ThorsAnvil::Serialize::jsonExport;
using ThorsAnvil::Serialize::jsonImport;
Example e1 {"Some Text", {{"ace", "the best"}, {"king", "second best"}}, {1 ,2 ,3, 4}};
// Simply serialize object to json using a stream.
std::cout << jsonExport(e1) << "\n";
// Deserialize json text from a stream into object.
std::cin >> jsonImport(e1);
}
Running:
{
"string": "Some Text",
"map":
{
"ace": "the best",
"king": "second best"
},
"vector": [ 1, 2, 3, 4]
}
You cannot do better than this in C++.
I wrote a library which designed to solve your problem. However, it is a very new project, not stable enough. Feel free to take a look, the homepage is here::
https://github.com/Mizuchi/acml
In your example, you have to add one line like this:
ACML_REGISTER(Example, ,(string)(map)(vector));
in order to tell the library which member you want to dump. Since C++ have no reflection. And you must give a way to access the member, either use public member level or use friend class.
And later you just need to do sth like this:
string result = acml::json::dumps(any_object);
would become::
{
"string": "the-string-value",
"map":
{
"key1": "val1",
"key2": "val2"
},
"vector":
{
"type": "std::vector",
"size": "4",
"0": "1",
"1": "2",
"2": "3",
"3": "4"
}
}
As you see, JSON array is not implemented yet. And everything becomes string now.
Do you want to JSON-ify a map or an object? (your example shows a class, yet you say a map). For a map, check out this library - JSON Spirit.
For objects: There is no reflection support in C++ (apart from the very limited RTTI), so there is no "one-click" solution for serialization either. Any solution will require you to write additional, possibly tightly coupled code to the class you want to serialize and de-serialize (that depends on if you want to serialize non-public data).