首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用from_json反序列化结构时: error:没有调用nlohmann::basic_json<>::get的匹配函数

用from_json反序列化结构时: error:没有调用nlohmann::basic_json<>::get的匹配函数
EN

Stack Overflow用户
提问于 2021-12-04 17:56:38
回答 1查看 728关注 0票数 1

我正在使用nlohmann/json库,并试图为我的一个结构实现序列化和反序列化。我要经过这个例子

这是结构和相关类型:

代码语言:javascript
运行
复制
typedef std::uint32_t vertex_key;
typedef std::uint64_t edge_key;
inline edge_key get_edge_key(vertex_key v1, vertex_key v2) {
    return (std::uint64_t)v1 << 32 | (std::uint64_t)v2;  // edge 64b = (v1 32b, v2 32b)
}

struct Mcnfmq {
    unsigned int n_nodes;
    vertex_key source;
    vertex_key sink;
    unsigned int flow_value;

    std::unordered_map<edge_key, int> costs;
    std::unordered_map<edge_key, int> capacities;
    std::unordered_map<edge_key, int> minimum_quantities;

    Mcnfmq(unsigned int n_nodes, vertex_key source, vertex_key sink, unsigned int flow_value)
        : n_nodes(n_nodes), source(source), sink(sink), flow_value(flow_value) {}
};

void to_json(json& j, const Mcnfmq& instance);
void from_json(const json& j, Mcnfmq& instance);

以下是to/from实现:

代码语言:javascript
运行
复制
void to_json(json& j, const Mcnfmq& instance) {
    j = json{
        {"n_nodes", instance.n_nodes},
        {"source", instance.source},
        {"sink", instance.sink},
        {"flow_value", instance.flow_value},
        {"costs", instance.costs},
        {"capacities", instance.capacities},
        {"minimum_quantities", instance.minimum_quantities},
    };
}

void from_json(const json& j, Mcnfmq& instance) {
    j.at("n_nodes").get_to(instance.n_nodes);
    j.at("source").get_to(instance.source);
    j.at("sink").get_to(instance.sink);
    j.at("flow_value").get_to(instance.flow_value);
    j.at("costs").get_to(instance.costs);
    j.at("capacities").get_to(instance.capacities);
    j.at("minimum_quantities").get_to(instance.minimum_quantities);
}

结构Mcnfmq和函数to_jsonfrom_json显然驻留在同一个名称空间(全局)中,所以这不应该是一个问题。

这是主要文件:

代码语言:javascript
运行
复制
int main() {
    std::ifstream i("output.json");
    json j2;
    i >> j2;
    i.close();

    Mcnfmq instance2 = j2.get<Mcnfmq>(); // ERROR HERE

    return 0;
}

全错误输出:

代码语言:javascript
运行
复制
test_serialization.cpp: In function 'int main()':
test_serialization.cpp:27:38: error: no matching function for call to 'nlohmann::basic_json<>::get<Mcnfmq>()'
   27 |     Mcnfmq instance2 = j2.get<Mcnfmq>();
      |                        ~~~~~~~~~~~~~~^~
In file included from test_serialization.cpp:6:
json.hpp:20717:10: note: candidate: 'template<class ValueTypeCV, class ValueType> constexpr decltype (declval<const basic_json_t&>().get_impl<ValueType>(nlohmann::detail::priority_tag<4>{})) nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType>::get() const [with ValueTypeCV = ValueTypeCV; ValueType = ValueType; ObjectType = std::map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long long int; NumberUnsignedType = long long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::adl_serializer; BinaryType = std::vector<unsigned char>]'
20717 |     auto get() const noexcept(
      |          ^~~
json.hpp:20717:10: note:   template argument deduction/substitution failed:
json.hpp: In substitution of 'template<class ValueTypeCV, class ValueType> constexpr decltype (declval<const basic_json_t&>().get_impl<ValueType>(nlohmann::detail::priority_tag<4>{})) nlohmann::basic_json<>::get<ValueTypeCV, ValueType>() const [with ValueTypeCV = Mcnfmq; ValueType = Mcnfmq]':
test_serialization.cpp:27:38:   required from here
json.hpp:20719:81: error: no matching function for call to 'nlohmann::basic_json<>::get_impl<Mcnfmq>(nlohmann::detail::priority_tag<4>) const'
20719 |     -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
      |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
json.hpp:20579:15: note: candidate: 'template<class ValueType, typename std::enable_if<(nlohmann::detail::is_default_constructible<T1>::value && nlohmann::detail::has_from_json<nlohmann::basic_json<>, ValueType, void>::value), int>::type <anonymous> > ValueType nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType>::get_impl(nlohmann::detail::priority_tag<0>) const [with ValueType = ValueType; typename std::enable_if<(nlohmann::detail::is_default_constructible<ValueType>::value && nlohmann::detail::has_from_json<nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType>, ValueType>::value), int>::type <anonymous> = <anonymous>; ObjectType = std::map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long long int; NumberUnsignedType = long long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::adl_serializer; BinaryType = std::vector<unsigned char>]'
20579 |     ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
      |               ^~~~~~~~
json.hpp:20579:15: note:   template argument deduction/substitution failed:
json.hpp:20578:28: error: no type named 'type' in 'struct std::enable_if<false, int>'
20578 |                    int > = 0 >
      |                            ^
json.hpp:20621:15: note: candidate: 'template<class ValueType, typename std::enable_if<nlohmann::detail::has_non_default_from_json<nlohmann::basic_json<>, ValueType, void>::value, int>::type <anonymous> > ValueType nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType>::get_impl(nlohmann::detail::priority_tag<1>) const [with ValueType = ValueType; typename std::enable_if<nlohmann::detail::has_non_default_from_json<nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType>, ValueType>::value, int>::type <anonymous> = <anonymous>; ObjectType = std::map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long long int; NumberUnsignedType = long long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::adl_serializer; BinaryType = std::vector<unsigned char>]'
20621 |     ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
      |               ^~~~~~~~
json.hpp:20621:15: note:   template argument deduction/substitution failed:
json.hpp:20620:28: error: no type named 'type' in 'struct std::enable_if<false, int>'
20620 |                    int > = 0 >
      |                            ^
json.hpp:20646:19: note: candidate: 'template<class BasicJsonType, typename std::enable_if<nlohmann::detail::is_basic_json<BasicJsonType>::value, int>::type <anonymous> > BasicJsonType nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType>::get_impl(nlohmann::detail::priority_tag<2>) const [with BasicJsonType = BasicJsonType; typename std::enable_if<nlohmann::detail::is_basic_json<BasicJsonType>::value, int>::type <anonymous> = <anonymous>; ObjectType = std::map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long long int; NumberUnsignedType = long long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::adl_serializer; BinaryType = std::vector<unsigned char>]'
20646 |     BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
      |                   ^~~~~~~~
json.hpp:20646:19: note:   template argument deduction/substitution failed:
json.hpp:20645:28: error: no type named 'type' in 'struct std::enable_if<false, int>'
20645 |                    int > = 0 >
      |                            ^
json.hpp:20669:16: note: candidate: 'template<class BasicJsonType, typename std::enable_if<std::is_same<BasicJsonType, nlohmann::basic_json<> >::value, int>::type <anonymous> > nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType> nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType>::get_impl(nlohmann::detail::priority_tag<3>) const [with BasicJsonType = BasicJsonType; typename std::enable_if<std::is_same<BasicJsonType, nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType> >::value, int>::type <anonymous> = <anonymous>; ObjectType = std::map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long long int; NumberUnsignedType = long long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::adl_serializer; BinaryType = std::vector<unsigned char>]'
20669 |     basic_json get_impl(detail::priority_tag<3> /*unused*/) const
      |                ^~~~~~~~
json.hpp:20669:16: note:   template argument deduction/substitution failed:
json.hpp:20668:25: error: no type named 'type' in 'struct std::enable_if<false, int>'
20668 |                  int> = 0>
      |                         ^
json.hpp:20682:20: note: candidate: 'template<class PointerType, typename std::enable_if<std::is_pointer<_Tp>::value, int>::type <anonymous> > constexpr decltype (declval<const basic_json_t&>().get_ptr<PointerType>()) nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType>::get_impl(nlohmann::detail::priority_tag<4>) const [with PointerType = PointerType; typename std::enable_if<std::is_pointer<_Ptr>::value, int>::type <anonymous> = <anonymous>; ObjectType = std::map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long long int; NumberUnsignedType = long long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::adl_serializer; BinaryType = std::vector<unsigned char>]'
20682 |     constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
      |                    ^~~~~~~~
json.hpp:20682:20: note:   template argument deduction/substitution failed:
json.hpp:20681:25: error: no type named 'type' in 'struct std::enable_if<false, int>'
20681 |                  int> = 0>
      |                         ^
json.hpp:20758:10: note: candidate: 'template<class PointerType, typename std::enable_if<std::is_pointer<_Tp>::value, int>::type <anonymous> > decltype (declval<nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType>::basic_json_t&>().get_ptr<PointerType>()) nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType>::get() [with PointerType = PointerType; typename std::enable_if<std::is_pointer<_Ptr>::value, int>::type <anonymous> = <anonymous>; ObjectType = std::map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long long int; NumberUnsignedType = long long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::adl_serializer; BinaryType = std::vector<unsigned char>]'
20758 |     auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
      |          ^~~
json.hpp:20758:10: note:   template argument deduction/substitution failed:
json.hpp:20757:68: error: no type named 'type' in 'struct std::enable_if<false, int>'
20757 |                  std::is_pointer<PointerType>::value, int>::type = 0>
      |                                                                    ^

我的问题:

  1. 错误信息到底在说什么?
  2. 怎么解决这个问题呢?
EN

回答 1

Stack Overflow用户

发布于 2021-12-04 17:56:38

我认为反序列化代码期望存在一个默认的构造函数。IIRC,向结构中添加自定义构造函数将删除默认构造函数。如果删除了自定义构造函数,或者显式地在struct声明(Mcnfmq() {})中添加了默认构造函数,问题就会得到解决。

(我当然会接受别人提供更好解释的答案。)

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

https://stackoverflow.com/questions/70228105

复制
相关文章

相似问题

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