Using custom types as JSON keys
Can I use a custom type as a key in a JSON object?
The JSON specification only allows strings as keys in objects. However, the nlohmann::json library provides a way to use other types as keys by converting them to strings.
To do this, you need to specialize the nlohmann::adl_serializer<T> struct for your type and provide to_json and from_json functions:
struct Weapon {
std::string name;
int damage;
};
namespace nlohmann {
template <>
struct adl_serializer<Weapon> {
static void to_json(json& j, const Weapon& w) {
j = w.name;
}
static void from_json(const json& j, Weapon& w) {
w.name = j.get<std::string>();
w.damage = 10;
}
};
}Here we've defined a Weapon struct. The to_json function converts a Weapon to a JSON string (just its name in this case), and from_json converts a JSON string back to a Weapon (setting a default damage of 10 since that information is lost in the string conversion).
Now we can use Weapon as a key in a JSON object:
#include <iostream>
#include <json.hpp>
using json = nlohmann::json;
struct Weapon {
std::string name;
int damage;
};
namespace nlohmann {
template <>
struct adl_serializer<Weapon> {
static void to_json(json& j, const Weapon& w) {
j = w.name; }
static void from_json(const json& j, Weapon& w) {
w.name = j.get<std::string>();
w.damage = 10;
}
};
}
int main() {
json character = {
{"name", "Lancelot"},
{"weapon", {{"name", "Sword"}, {"damage", 20}}},
{Weapon{"Dagger", 5}, "backup weapon"}
};
std::cout << character.dump(2);
}{
"Dagger": "backup weapon",
"name": "Lancelot",
"weapon": {
"damage": 20,
"name": "Sword"
}
}The Weapon{"Dagger", 5} key was converted to the string "Dagger" in the output JSON.
When using custom types as keys, keep in mind that all the type information is lost in the conversion to string. In this case, the damage property of the "Dagger" key is lost and would be set back to the default of 10 if we were to parse this JSON back into a C++ object.
So while custom type keys are possible, they're not always practical. It's often better to stick with string keys and put the custom types as values in the JSON object.
Using JSON in Modern C++
A practical guide to working with the JSON data format in C++ using the popular nlohmann::json library.