-
-
Notifications
You must be signed in to change notification settings - Fork 6.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Deserialization to std::array with non-default constructable types fails #2574
Comments
Related: #2575 |
The problem seems to be that So it seems to be less a problem of the library, but more the question: how to initialize a |
Issue #2575 seems wrong use of the library somehow? I don't see it being related to this at all, this is specifically about non-default constructible types. Initializing an array of such types is not really a problem in general. You can use #include <array>
#include <iostream>
#include <utility>
#include <vector>
struct NoDefConstructor {
explicit NoDefConstructor (int x) : x(x) { }
int x;
};
template <std::size_t... Is>
std::array<NoDefConstructor, sizeof...(Is)> to_array_impl (std::vector<NoDefConstructor> const & v,
std::index_sequence<Is...>) {
return { v.at(Is)... };
}
template <std::size_t N>
std::array<NoDefConstructor, N> to_array (std::vector<NoDefConstructor> const & v) {
return to_array_impl(v, std::make_index_sequence<N>());
}
int main() {
auto a = std::vector<NoDefConstructor>{ NoDefConstructor(7), NoDefConstructor(2) };
auto b = to_array<2>(a);
for (auto const & e : b) { std::cout << e.x << ' '; }
} You could always use this way of constructing an array when deserializing. Although that would generate different code for each combination of |
Ok, so we have a possible solution. Nice! |
I'm working on a pull request. Should be finished soon. |
Thanks so much. Sorry for the confusion - with two issues related to |
Yes, I found those implementations. I've just been spending the past half hour staring at where to put the code :). |
By the way, this same issue happens for |
Put them in the same. Thanks for checking! |
Ok, will do. Might take a bit longer than expected. I'm struggling to find the best place to put this. It seems it belongs in a specialization of |
…tructable types (fixes nlohmann#2574).
…_containers Add support for deserialization of STL containers of non-default constructable types (fixes #2574).
Compilations fails when trying to convert an
nlohmann::json
object to anstd::array<T, N>
, whereT
does not have a default constructor.What is the issue you have?
Compile error when trying to deserialize an
std::array
of non-default constructable types. However, deserialization from such types works fine if such a type is deserialized directly (i.e. not anstd::array
of it), or if e.g. anstd::vector
of such types is deserialized.Hence it seems to me that this limitation is purely due to the way deserialization is implemented for
std::array
. Of course for e.g.std::vector
this is not an issue anyway, since there you can constructor thestd::vector
first and thenemplace_back()
objects into it, which isn't possible forstd::array
in this case.I haven't really looked into it, but I would think that using pack expansion (with most likely some extra helper structs thrown in) would allow creating the requested
std::array
in "one go" (i.e. no creating it beforehand and then assigning values to each location).Please describe the steps to reproduce the issue.
Live example here: https://godbolt.org/z/qxP5aE
Can you provide a small but working code example?
What is the expected behavior?
Code compiles and returns the requested
std::array
.And what is the actual behavior instead?
nlohmann::json 3.7.1: Compile error that the function
get<std::array<NoDefaultConstructor, 2>>
does not exist:nlohmann::json 3.6.0: Static assert goes off complaining that
get<T>()
doesn't allowT
to be non-default constructable.Which compiler and operating system are you using?
Which version of the library did you use?
develop
branchIf you experience a compilation error: can you compile and run the unit tests?
The text was updated successfully, but these errors were encountered: