How to serialize/deserialize custom class templates with nlohmann::json

188 Views Asked by At

For some reason I get conversion errors with this code:

template<typename T>
class MyType {
    T data;
};

template<typename T>
void from_json(MyType<T>& t, const nlohmann::json& j) {}

template<typename T>
void to_json(const MyType<T>& t, nlohmann::json& j) {}

int main() {
    MyType<std::string> f;
    nlohmann::json j = f; //error
    f = j.template get<MyType<std::string>>(); //error
}

I'm writing a library type that uses nlohmann::json and I would not like the user to have to write boilerplate serialization for every template instantiation. Is there a way to do this? If not, why exactly is the compiler complaining?

1

There are 1 best solutions below

0
On BEST ANSWER

You have got the parameters of from_json and to_json inverted. The signatures of from_json and to_json are:

template<typename ValueType>
struct adl_serializer {
    template<typename BasicJsonType>
    static void to_json(BasicJsonType& j, const T& value) {
        // calls the "to_json" method in T's namespace
    }

    template<typename BasicJsonType>
    static void from_json(const BasicJsonType& j, T& value) {
        // same thing, but with the "from_json" method
    }
};

Therefore, you should list Json as the first parameter. Once you do that, the code compiles successfully.

Fixed code:

template<typename T>
class MyType {
    T data;
};

template<typename T>
void from_json(const nlohmann::json& j, MyType<T>& t) {}

template<typename T>
void to_json(nlohmann::json& j, const MyType<T>& t) {}

int main() {
    MyType<std::string> f;
    nlohmann::json j = f;
    f = j.template get<MyType<std::string>>();
}

Demo: https://godbolt.org/z/fsev5snd6