我希望用nlohmann序列化一个std::optional<float>。
给出的在这里的医生用于boost::optional的例子似乎非常接近我想要的,但我不知道我对它的适应有什么问题。
反序列化组件似乎适用于我,而不是to_json方面。
下面是一个最小的工作示例
// 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中编译,其错误如下
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我的具体要求是
我注意到关于这个项目的一些相当长的讨论在将std::optionals集成到库本身时遇到了困难,尽管我没有完全遵循它,并且理解它对我的实际意义,希望使用std::optional作为第三方对象。有些评论提出了类似于我在这里工作的方法,所以我希望这是一个疏忽/愚蠢的错误。
干杯!
发布于 2022-06-30 07:04:17
这相当于一个愚蠢的-一个很难发现,因为你太担心它的一些深奥的东西。对于我的错误来说,这可能是非常具体的,而且对将来发现这一点的人来说也不会有太大的用处。尽管如此,答案如下。
我的MWE是一个真正的代码基的简化。该代码库专门使用orderd_json,但将其简短地交给json,即
using json = nlohmann::ordered_json;在json中使用单词nlohmann的类是一个不同的、更一般的类。看起来,当序列化到一个ordered_json时,它需要专门针对ordered_json类型,并且不能自动地引导它。
也就是说,我应该以to_json类型ordered_json作为第一个论点。
static void to_json(ordered_json& j, const std::optional<T>& opt) {/*...*/}而不是
static void to_json(json& j, const std::optional<T>& opt) {/*...*/}结果from_json还是起了作用。
https://stackoverflow.com/questions/72800031
复制相似问题