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.

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

Creating a JSON object from a file
How can I create a JSON object by reading the contents of a JSON file?
Checking if a key exists in JSON
What is the best way to check if a specific key exists in a JSON object?
Pretty-printing JSON
How can I print out JSON in a nicely formatted way?
Serializing private class members to JSON
How can I serialize private members of a class to JSON?
Adding comments to JSON
Can I add comments to a JSON file to document what certain parts mean?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant