首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >序列化/反序列化std::可选的nlohmann-json

序列化/反序列化std::可选的nlohmann-json
EN

Stack Overflow用户
提问于 2022-06-29 10:42:30
回答 1查看 294关注 0票数 1

我希望用nlohmann序列化一个std::optional<float>

给出的在这里的医生用于boost::optional的例子似乎非常接近我想要的,但我不知道我对它的适应有什么问题。

反序列化组件似乎适用于我,而不是to_json方面。

下面是一个最小的工作示例

代码语言:javascript
复制
// OptionalSeriealisationTest.cpp 

//#define JSON_USE_IMPLICIT_CONVERSIONS 0 
// Tried toggling this as per this comment 
// https://github.com/nlohmann/json/issues/1749#issuecomment-772996219 with no effect
// (no effect noticed)

#include <iostream>
#include <optional>
#include <nlohmann/json.hpp>
namespace nlohmann
{
    template <typename T>
    struct adl_serializer<std::optional<T>>
    {
        // This one is the issue
        static void to_json(json& j, const std::optional<T>& opt) {
            //if (opt == std::nullopt) {
            //  j = nullptr;
            //}
            //else {
            //  j = *opt; // this will call adl_serializer<t>::to_json which will
            //            // find the free function to_json in t's namespace!

            //}


            if (opt)
            {
                j = opt.value();
            }
            else
            {
                j = nullptr;
            }

            //NB same errors on the block above and the commented-out version

        }

        static void from_json(const json& j, std::optional<T>& opt) {
            if (j.is_null()) {
                opt = std::nullopt;
            }
            else {
                opt = j.get<T>(); // same as above, but with
                                  // adl_serializer<t>::from_json
            }
        }
    };
}

using json = nlohmann::ordered_json;

int main()
{
    {
        // Seems ok, breakpoints on the from_json are hit
        json j;
        j["x"] = 4.0f;
        std::optional<float> x;
        j.at("x").get_to<std::optional<float>>(x);
        std::cout <<  x.has_value() << std::endl;
        std::cout << x.value() << std::endl;
    }

    {
        // Seems ok, breakpoints on the from_json are hit
        json j;
        j["x"] = nullptr;
        std::optional<float> x = 4.0f;
        j.at("x").get_to<std::optional<float>>(x);
        std::cout << x.has_value() << std::endl;
        //std::cout << x.value() << std::endl;
    }

    {
        // Won't compile on MSVC
        std::optional<float> x = 4.0;
        json j;
        j["x"] = x; 
    }

    {
        // Won't compile on MSVC
        std::optional<float> x = 4.0;
        auto j = json({ "x", x });
    }

}

to_json方面不会在MSVC中编译,其错误如下

代码语言:javascript
复制
Severity    Code    Description Project File    Line    Suppression State
Error (active)  E0289

no instance of constructor

"nlohmann::basic_json<ObjectType, ArrayType, StringType,
BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType,
AllocatorType, JSONSerializer, BinaryType>::basic_json

[with ObjectType=nlohmann::ordered_map, ArrayType=std::vector,
StringType=std::string, BooleanType=bool, NumberIntegerType=int64_t,
NumberUnsignedType=uint64_t, NumberFloatType=double,
AllocatorType=std::allocator, JSONSerializer=nlohmann::adl_serializer,
BinaryType=std::vector<uint8_t, std::allocator<uint8_t>>]"

matches the argument list

我的具体要求是

  • 解决办法是什么?
  • 为什么这会出错,因为它似乎如此接近他们的例子(boost::optional::可选?)

我注意到关于这个项目的一些相当长的讨论在将std::optionals集成到库本身时遇到了困难,尽管我没有完全遵循它,并且理解它对我的实际意义,希望使用std::optional作为第三方对象。有些评论提出了类似于我在这里工作的方法,所以我希望这是一个疏忽/愚蠢的错误。

干杯!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-06-30 07:04:17

这相当于一个愚蠢的-一个很难发现,因为你太担心它的一些深奥的东西。对于我的错误来说,这可能是非常具体的,而且对将来发现这一点的人来说也不会有太大的用处。尽管如此,答案如下。

我的MWE是一个真正的代码基的简化。该代码库专门使用orderd_json,但将其简短地交给json,即

代码语言:javascript
复制
using json = nlohmann::ordered_json;

json中使用单词nlohmann的类是一个不同的、更一般的类。看起来,当序列化到一个ordered_json时,它需要专门针对ordered_json类型,并且不能自动地引导它。

也就是说,我应该以to_json类型ordered_json作为第一个论点。

代码语言:javascript
复制
        static void to_json(ordered_json& j, const std::optional<T>& opt) {/*...*/}

而不是

代码语言:javascript
复制
        static void to_json(json& j, const std::optional<T>& opt) {/*...*/}

结果from_json还是起了作用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72800031

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档