Json: Support serialisation of `unique_ptr<>` and `shared_ptr<>`

Created on 16 Feb 2018  路  8Comments  路  Source: nlohmann/json

If you try something like this:

std::unique_ptr<int> a = ...;
json j = a;

It will fail with a template error (get_json() isn't defined for unique_ptr). I can't see a good reason why that shouldn't work by default. I would expect null for null pointers and the actual value otherwise.

proposed fix

Most helpful comment

I am also not sure whether such an implicit dereference under the hood is adding simplicity or rather surprise.

In any case, the described behavior can be achieved without changing the library:

#include "json.hpp"
#include <iostream>

using json = nlohmann::json;

namespace nlohmann {
    template <typename T>
    struct adl_serializer<std::unique_ptr<T>> {
        static void to_json(json& j, const std::unique_ptr<T>& opt) {
            if (opt.get()) {
                j = *opt;
            } else {
                j = nullptr;
            }
        }
    };
}

int main()
{
    std::unique_ptr<int> a = std::make_unique<int>(1);
    std::unique_ptr<int> b;
    json j = {a, b};

    std::cout << j << std::endl;
}

(prints [1,null])

All 8 comments

I'm just a user, but I don't think having this library supporting automatic pointer dereference is a good idea.

Because...

I am also not sure whether such an implicit dereference under the hood is adding simplicity or rather surprise.

In any case, the described behavior can be achieved without changing the library:

#include "json.hpp"
#include <iostream>

using json = nlohmann::json;

namespace nlohmann {
    template <typename T>
    struct adl_serializer<std::unique_ptr<T>> {
        static void to_json(json& j, const std::unique_ptr<T>& opt) {
            if (opt.get()) {
                j = *opt;
            } else {
                j = nullptr;
            }
        }
    };
}

int main()
{
    std::unique_ptr<int> a = std::make_unique<int>(1);
    std::unique_ptr<int> b;
    json j = {a, b};

    std::cout << j << std::endl;
}

(prints [1,null])

Can I close this issue?

Yep, sorry for the delay - that looks excellent. Given that it is that easy to do without changing the library I wouldn't change it either. Though maybe add it to the Readme?

There is already an example for boost::optional in the Readme, so I don't think adding one for unique_ptr/shared_ptr is very useful.

Shouldn't at least std::optional be supported?

For std::optional, see #2229.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Fonger picture Fonger  路  4Comments

afowles picture afowles  路  3Comments

koemeet picture koemeet  路  4Comments

zkelo picture zkelo  路  3Comments

qis picture qis  路  4Comments