Skip to content

value_to with described structs containing POD arrays: "error: invalid array assignment" #1084

@hsteinhaus

Description

@hsteinhaus

When trying to serialize a struct containing a array of int, I get the following error:

/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/json/detail/value_to.hpp:387:33: error: invalid array assignment
  387 |             (*res).* D::pointer = std::move(*member_res);
      |             ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
In file included from /opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/c++/13.3.0/bits/ranges_base.h:37,
                 from /opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/c++/13.3.0/bits/ranges_util.h:34,
                 from /opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/c++/13.3.0/tuple:44,
                 from /opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/mp11/tuple.hpp:15,
                 from /opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/mp11.hpp:20,
                 from /home/holger-local/CLionProjects/untitled/main.cpp:4:
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/c++/13.3.0/bits/stl_iterator.h: In instantiation of ‘class std::insert_iterator<int [2]>’:
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/json/detail/value_to.hpp:271:32:   required from ‘boost::json::result<T> boost::json::detail::value_to_impl(sequence_conversion_tag, boost::json::try_value_to_tag<T>, const boost::json::value&, const Ctx&) [with T = int [2]; Ctx = std::tuple<allow_exceptions, no_context>; boost::json::result<T> = boost::system::result<int [2], boost::system::error_code>]’
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/json/value_to.hpp:230:33:   required from ‘typename boost::json::result_for<T, boost::json::value>::type boost::json::try_value_to(const value&, const Context&) [with T = int [2]; Context = std::tuple<detail::allow_exceptions, detail::no_context>; typename result_for<T, value>::type = boost::system::result<int [2], boost::system::error_code>]’
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/json/detail/value_to.hpp:381:42:   required from ‘void boost::json::detail::to_described_member<Ctx, T, non_throwing>::operator()(I) [with I = std::integral_constant<long unsigned int, 2>; Ctx = std::tuple<boost::json::detail::allow_exceptions, boost::json::detail::no_context>; T = app::A; bool non_throwing = true]’
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/mp11/algorithm.hpp:1060:29:   required from ‘constexpr F boost::mp11::detail::mp_for_each_impl(boost::mp11::mp_list<Q ...>, F&&) [with T = {std::integral_constant<long unsigned int, 0>, std::integral_constant<long unsigned int, 1>, std::integral_constant<long unsigned int, 2>}; F = boost::json::detail::to_described_member<std::tuple<boost::json::detail::allow_exceptions, boost::json::detail::no_context>, app::A, true>&]’
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/mp11/algorithm.hpp:1093:36:   required from ‘boost::json::result<T> boost::json::detail::value_to_impl(described_class_conversion_tag, boost::json::try_value_to_tag<T>, const boost::json::value&, const Ctx&) [with T = app::A; Ctx = std::tuple<allow_exceptions, no_context>; boost::json::result<T> = boost::system::result<app::A, boost::system::error_code>]’
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/json/detail/value_to.hpp:855:25:   required from ‘T boost::json::detail::value_to_impl(Impl, boost::json::value_to_tag<T>, const boost::json::value&, const Ctx&) [with Impl = described_class_conversion_tag; T = app::A; Ctx = no_context]’
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/json/value_to.hpp:96:33:   required from ‘T boost::json::value_to(const value&, const Context&) [with T = app::A; Context = detail::no_context]’
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/json/value_to.hpp:148:23:   required from ‘T boost::json::value_to(const value&) [with T = app::A]’
/home/holger-local/CLionProjects/untitled/main.cpp:42:43:   required from here
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/c++/13.3.0/bits/stl_iterator.h:966:7: error: ‘int [2]’ is not a class, struct, or union type
  966 |       operator=(const typename _Container::value_type& __value)
      |       ^~~~~~~~
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/c++/13.3.0/bits/stl_iterator.h:975:7: error: ‘int [2]’ is not a class, struct, or union type
  975 |       operator=(typename _Container::value_type&& __value)
      |       ^~~~~~~~
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/json/detail/value_to.hpp: In instantiation of ‘boost::json::result<T> boost::json::detail::value_to_impl(sequence_conversion_tag, boost::json::try_value_to_tag<T>, const boost::json::value&, const Ctx&) [with T = int [2]; Ctx = std::tuple<allow_exceptions, no_context>; boost::json::result<T> = boost::system::result<int [2], boost::system::error_code>]’:
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/json/value_to.hpp:230:33:   required from ‘typename boost::json::result_for<T, boost::json::value>::type boost::json::try_value_to(const value&, const Context&) [with T = int [2]; Context = std::tuple<detail::allow_exceptions, detail::no_context>; typename result_for<T, value>::type = boost::system::result<int [2], boost::system::error_code>]’
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/json/detail/value_to.hpp:381:42:   required from ‘void boost::json::detail::to_described_member<Ctx, T, non_throwing>::operator()(I) [with I = std::integral_constant<long unsigned int, 2>; Ctx = std::tuple<boost::json::detail::allow_exceptions, boost::json::detail::no_context>; T = app::A; bool non_throwing = true]’
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/mp11/algorithm.hpp:1060:29:   required from ‘constexpr F boost::mp11::detail::mp_for_each_impl(boost::mp11::mp_list<Q ...>, F&&) [with T = {std::integral_constant<long unsigned int, 0>, std::integral_constant<long unsigned int, 1>, std::integral_constant<long unsigned int, 2>}; F = boost::json::detail::to_described_member<std::tuple<boost::json::detail::allow_exceptions, boost::json::detail::no_context>, app::A, true>&]’
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/mp11/algorithm.hpp:1093:36:   required from ‘boost::json::result<T> boost::json::detail::value_to_impl(described_class_conversion_tag, boost::json::try_value_to_tag<T>, const boost::json::value&, const Ctx&) [with T = app::A; Ctx = std::tuple<allow_exceptions, no_context>; boost::json::result<T> = boost::system::result<app::A, boost::system::error_code>]’
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/json/detail/value_to.hpp:855:25:   required from ‘T boost::json::detail::value_to_impl(Impl, boost::json::value_to_tag<T>, const boost::json::value&, const Ctx&) [with Impl = described_class_conversion_tag; T = app::A; Ctx = no_context]’
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/json/value_to.hpp:96:33:   required from ‘T boost::json::value_to(const value&, const Context&) [with T = app::A; Context = detail::no_context]’
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/json/value_to.hpp:148:23:   required from ‘T boost::json::value_to(const value&) [with T = app::A]’
/home/holger-local/CLionProjects/untitled/main.cpp:42:43:   required from here
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/json/detail/value_to.hpp:277:16: error: no match for ‘operator=’ (operand types are ‘std::insert_iterator<int [2]>’ and ‘std::remove_reference<int&>::type’ {aka ‘int’})
  277 |         *ins++ = std::move(*elem_res);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/c++/13.3.0/bits/stl_iterator.h:904:11: note: candidate: ‘constexpr std::insert_iterator<int [2]>& std::insert_iterator<int [2]>::operator=(const std::insert_iterator<int [2]>&)’
  904 |     class insert_iterator
      |           ^~~~~~~~~~~~~~~
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/c++/13.3.0/bits/stl_iterator.h:904:11: note:   no known conversion for argument 1 from ‘std::remove_reference<int&>::type’ {aka ‘int’} to ‘const std::insert_iterator<int [2]>&’
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/c++/13.3.0/bits/stl_iterator.h:904:11: note: candidate: ‘constexpr std::insert_iterator<int [2]>& std::insert_iterator<int [2]>::operator=(std::insert_iterator<int [2]>&&)’
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/c++/13.3.0/bits/stl_iterator.h:904:11: note:   no known conversion for argument 1 from ‘std::remove_reference<int&>::type’ {aka ‘int’} to ‘std::insert_iterator<int [2]>&&’
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/json/detail/value_to.hpp:279:12: error: could not convert ‘result’ from ‘int [2]’ to ‘boost::json::result<int [2]>’ {aka ‘boost::system::result<int [2], boost::system::error_code>’}
  279 |     return result;
      |            ^~~~~~
      |            |
      |            int [2]
In file included from /opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/json/conversion.hpp:398,
                 from /opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/json.hpp:17:
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/json/impl/conversion.hpp: In instantiation of ‘std::insert_iterator<_Container> boost::json::detail::inserter(T&, boost::mp11::mp_int<0>) [with T = int [2]; boost::mp11::mp_int<0> = std::integral_constant<int, 0>]’:
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/json/detail/value_to.hpp:271:32:   required from ‘boost::json::result<T> boost::json::detail::value_to_impl(sequence_conversion_tag, boost::json::try_value_to_tag<T>, const boost::json::value&, const Ctx&) [with T = int [2]; Ctx = std::tuple<allow_exceptions, no_context>; boost::json::result<T> = boost::system::result<int [2], boost::system::error_code>]’
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/json/value_to.hpp:230:33:   required from ‘typename boost::json::result_for<T, boost::json::value>::type boost::json::try_value_to(const value&, const Context&) [with T = int [2]; Context = std::tuple<detail::allow_exceptions, detail::no_context>; typename result_for<T, value>::type = boost::system::result<int [2], boost::system::error_code>]’
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/json/detail/value_to.hpp:381:42:   required from ‘void boost::json::detail::to_described_member<Ctx, T, non_throwing>::operator()(I) [with I = std::integral_constant<long unsigned int, 2>; Ctx = std::tuple<boost::json::detail::allow_exceptions, boost::json::detail::no_context>; T = app::A; bool non_throwing = true]’
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/mp11/algorithm.hpp:1060:29:   required from ‘constexpr F boost::mp11::detail::mp_for_each_impl(boost::mp11::mp_list<Q ...>, F&&) [with T = {std::integral_constant<long unsigned int, 0>, std::integral_constant<long unsigned int, 1>, std::integral_constant<long unsigned int, 2>}; F = boost::json::detail::to_described_member<std::tuple<boost::json::detail::allow_exceptions, boost::json::detail::no_context>, app::A, true>&]’
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/mp11/algorithm.hpp:1093:36:   required from ‘boost::json::result<T> boost::json::detail::value_to_impl(described_class_conversion_tag, boost::json::try_value_to_tag<T>, const boost::json::value&, const Ctx&) [with T = app::A; Ctx = std::tuple<allow_exceptions, no_context>; boost::json::result<T> = boost::system::result<app::A, boost::system::error_code>]’
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/json/detail/value_to.hpp:855:25:   required from ‘T boost::json::detail::value_to_impl(Impl, boost::json::value_to_tag<T>, const boost::json::value&, const Ctx&) [with Impl = described_class_conversion_tag; T = app::A; Ctx = no_context]’
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/json/value_to.hpp:96:33:   required from ‘T boost::json::value_to(const value&, const Context&) [with T = app::A; Context = detail::no_context]’
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/json/value_to.hpp:148:23:   required from ‘T boost::json::value_to(const value&) [with T = app::A]’
/home/holger-local/CLionProjects/untitled/main.cpp:42:43:   required from here
/opt/fslc-emo/6.6-scarthgap/sysroots/cortexa53-fslc-linux/usr/include/boost/json/impl/conversion.hpp:170:42: error: request for member ‘end’ in ‘target’, which is of non-class type ‘int [2]’
  170 |     return std::inserter( target, target.end() );
      |                                   ~~~~~~~^~~

To reproduce the error, I have modified the example boost::describe is providing here: https://www.boost.org/doc/libs/latest/libs/describe/doc/html/describe.html#example_from_json . Unfortunetely, there seems to be no easy work-around with a custom tag_invoke, because an implentation for the array is already available by default.

#include <boost/describe.hpp>
#include <boost/mp11.hpp>
#include <boost/json.hpp>
#include <boost/version.hpp>
#include <type_traits>

using namespace boost::json;

namespace app
{


    struct A
    {
        int x;
        int y;
        int b[2];  // the breaking change
    };

BOOST_DESCRIBE_STRUCT(A, (), (x, y, b))

} // namespace app

#include <iostream>

int main()
{
    boost::json::value jv{ { "x", 1 }, { "y", 2 }, {"b", {1, 2}} };

    std::cout << "jv: " << jv << std::endl;

    auto a = boost::json::value_to<app::A>( jv );

    std::cout << "a: { " << a.x << ", " << a.y << " }" << std::endl;
}

The compiler used for the error output given above is a custom embedded cross compiler (GCC 13.3.0), but I do not expect that this problem is specific to this compiler.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions