Skip to content

ordered_json doesn't support construction from C array of custom type #3810

Closed

Description

@lethal-guitar

Description

I have a C-style array of structs, plus an appropriate to_json overload. I can succesfully convert the array to JSON using a regular nlohmann::json object. However, trying to do the same using nlohmann::ordered_json fails to compile - see details below.

Reproduction steps

See the example code below.

Expected vs. actual results

I'd expect the code to compile, but I get a compiler error.

Minimal code example

Build with -std=c++17 -O3.

#include <nlohmann/json.hpp>

struct Example
{
    int bla;
};

NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Example, bla);

int main()
{
    Example states[45];

    // This works:
    nlohmann::json j;
    j["test"] = states;

    // This doesn't compile:
    nlohmann::ordered_json oj;
    oj["test"] = states;
}

Error messages

gcc 9.4.0 reports:

In file included from /opt/compiler-explorer/gcc-9.4.0/include/c++/9.4.0/vector:66,
                 from /opt/compiler-explorer/gcc-9.4.0/include/c++/9.4.0/functional:62,
                 from /opt/compiler-explorer/gcc-9.4.0/include/c++/9.4.0/pstl/glue_algorithm_defs.h:13,
                 from /opt/compiler-explorer/gcc-9.4.0/include/c++/9.4.0/algorithm:71,
                 from /opt/compiler-explorer/libs/nlohmann_json/v3.11.1/single_include/nlohmann/json.hpp:21,
                 from <source>:1:
/opt/compiler-explorer/gcc-9.4.0/include/c++/9.4.0/bits/stl_uninitialized.h: In instantiation of '_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = const Example*; _ForwardIterator = nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map>*]':
/opt/compiler-explorer/gcc-9.4.0/include/c++/9.4.0/bits/stl_uninitialized.h:307:37:   required from '_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = const Example*; _ForwardIterator = nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map>*; _Tp = nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map>]'
/opt/compiler-explorer/gcc-9.4.0/include/c++/9.4.0/bits/stl_vector.h:1582:33:   required from 'void std::vector<_Tp, _Alloc>::_M_range_initialize(_ForwardIterator, _ForwardIterator, std::forward_iterator_tag) [with _ForwardIterator = const Example*; _Tp = nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map>; _Alloc = std::allocator<nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map> >]'
/opt/compiler-explorer/gcc-9.4.0/include/c++/9.4.0/bits/stl_vector.h:654:4:   required from 'std::vector<_Tp, _Alloc>::vector(_InputIterator, _InputIterator, const allocator_type&) [with _InputIterator = const Example*; <template-parameter-2-2> = void; _Tp = nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map>; _Alloc = std::allocator<nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map> >; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map> >]'
/opt/compiler-explorer/gcc-9.4.0/include/c++/9.4.0/ext/new_allocator.h:146:4:   required from 'void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = std::vector<nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map>, std::allocator<nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map> > >; _Args = {const Example*, const Example*}; _Tp = std::vector<nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map>, std::allocator<nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map> > >]'
/opt/compiler-explorer/gcc-9.4.0/include/c++/9.4.0/bits/alloc_traits.h:483:4:   [ skipping 2 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/opt/compiler-explorer/libs/nlohmann_json/v3.11.1/single_include/nlohmann/json.hpp:5412:25:   required from 'static void nlohmann::json_v3_11_1::detail::external_constructor<nlohmann::json_v3_11_1::detail::value_t::array>::construct(BasicJsonType&, const CompatibleArrayType&) [with BasicJsonType = nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map>; CompatibleArrayType = Example [45]; typename std::enable_if<(! std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value), int>::type <anonymous> = 0]'
/opt/compiler-explorer/libs/nlohmann_json/v3.11.1/single_include/nlohmann/json.hpp:5607:52:   required from 'void nlohmann::json_v3_11_1::detail::to_json(BasicJsonType&, const T (&)[N]) [with BasicJsonType = nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map>; T = Example; long unsigned int N = 45; typename std::enable_if<(! std::is_constructible<typename BasicJsonType::string_t, const T (&)[N]>::value), int>::type <anonymous> = 0]'
/opt/compiler-explorer/libs/nlohmann_json/v3.11.1/single_include/nlohmann/json.hpp:5650:23:   required from 'decltype ((nlohmann::json_v3_11_1::detail::to_json(j, forward<T>(val)), void())) nlohmann::json_v3_11_1::detail::to_json_fn::operator()(BasicJsonType&, T&&) const [with BasicJsonType = nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map>; T = Example (&)[45]; decltype ((nlohmann::json_v3_11_1::detail::to_json(j, forward<T>(val)), void())) = void]'
/opt/compiler-explorer/libs/nlohmann_json/v3.11.1/single_include/nlohmann/json.hpp:5706:28:   required from 'static decltype ((nlohmann::json_v3_11_1::to_json(j, forward<TargetType>(val)), void())) nlohmann::json_v3_11_1::adl_serializer<T, SFINAE>::to_json(BasicJsonType&, TargetType&&) [with BasicJsonType = nlohmann::json_v3_11_1::basic_json<nlohmann::json_v3_11_1::ordered_map>; TargetType = Example (&)[45]; ValueType = Example [45]; <template-parameter-1-2> = void; decltype ((nlohmann::json_v3_11_1::to_json(j, forward<TargetType>(val)), void())) = void]'
/opt/compiler-explorer/libs/nlohmann_json/v3.11.1/single_include/nlohmann/json.hpp:19798:35:   required from 'nlohmann::json_v3_11_1::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType>::basic_json(CompatibleType&&) [with CompatibleType = Example (&)[45]; U = Example [45]; typename std::enable_if<((! nlohmann::json_v3_11_1::detail::is_basic_json<U>::value) && nlohmann::json_v3_11_1::detail::is_compatible_type<nlohmann::json_v3_11_1::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType>, U>::value), int>::type <anonymous> = 0; ObjectType = nlohmann::json_v3_11_1::ordered_map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long int; NumberUnsignedType = long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::json_v3_11_1::adl_serializer; BinaryType = std::vector<unsigned char>]'
<source>:20:18:   required from here
/opt/compiler-explorer/gcc-9.4.0/include/c++/9.4.0/bits/stl_uninitialized.h:127:72: error: static assertion failed: result type must be constructible from value type of input range
  127 |       static_assert(is_constructible<_ValueType2, decltype(*__first)>::value,
      |

Clang outputs a significantly longer error message, which boils down to "No matching constructor found".

Compiler and operating system

GCC 9.4 on Linux (godbolt), Apple Clang 10 on Mac OS

Library version

3.11.1

Validation

Activity

  1. falbrechtskirchinger commented on Nov 4, 2022

    @falbrechtskirchinger
    Contributor

    This will be fixed by #2843. In the meantime, this can be solved by writing from_json/to_json functions that accept arbitrary basic_json types (or just ordered_json in your case).

  2. lethal-guitar commented on Nov 4, 2022

    @lethal-guitar
    Author

    I see, thanks!

  3. added this to the Release 3.11.4 milestone on Jan 19, 2025
  4. nlohmann commented on Jan 19, 2025

    @nlohmann
    Owner

    Fixed by merging #4597.

  5. added a commit that references this issue on Feb 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind: bugsolution: proposed fixa fix for the issue has been proposed and waits for confirmation

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      ⌂ 换网址