Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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
Add conversion from/to std::optional #2117
base: develop
Are you sure you want to change the base?
Add conversion from/to std::optional #2117
Changes from 13 commits
df30a0e
1359c56
713038f
1b846c9
a2fea87
6b31375
71c80cc
007c6c4
f25bf31
b61d563
fedf82c
5e55158
ebb63bd
f1913fe
384442e
7ffd3ae
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initialization of
optional<T>
from emptyjson
should be considered as atype_error
:The reason is as follows. If
json
is implicitly convertible toT
, then initialization ofoptional<T>
fromjson
almost necessarily goes through the "forwarding" constructor:This constructor provides the best parameter/argument match by value category, constness and a type. Its parameter binds directly to
json
in any form. The only "weakness" of the forwarding constructor is that it is a template. A conversion function that would be considered as a better candidate for overload resolution must be non-templated, but this is obviously unacceptable.The forwarding constructor converts
json
toT
(initializes the latter from the former) and stores the result, so the constructedoptional<T>
cannot be empty. Such a conversion from emptyjson
toT
is atype error
(even ifT
itself isoptional<X>
, by induction).The non-standard overload resolution performed by GCC and Clang when enabling C++17 does not change the outcome. The only way to achieve the "natural" behavior is to tune constructors of
std::optional<T>
, which is beyond the scope of the project.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is also the usual way to explicitly convert
json
tooptional<T>
. The following will work:There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Essentially, there is nothing new here. @dota17 proposed the same in #2213.
However, this approach (treat such initialization as
type_error
) introduces some inconsistency:Perhaps it makes sense to throw
type_error
in the first case too?The "natural" conversion could be explicitly implemented by dedicated member function:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moreover, as it turns out, this dedicated member function is the only meaningful thing
nlohmann::basic_json
can provide to supportstd::optional
. Overloads ofget<std::optional<T>>
should probably be disabled to prevent confusion.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the behavior is counter-intuitive. JSON's
null
is usually considered as "unset" value (in contrast to an empty value). Therefore, I would expectnull
to convert tostd::nullopt
of any optional type.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Direct initialization of
vector<...>
is not suitable here:Such kind of initialization of
vector<...>
has not been tested even with simple item types and actually leads to a compile error for the reason considered earlier. For example, the following will not compile unless using GCC or Clang with C++17 enabled (see https://godbolt.org/z/oeooPG):There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Direct initialization of
map<...>
has the same trouble as withvector<...>
above: