Skip to content

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

@lethal-guitar

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

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