* Make cross-string-type basic_json conversion explicit without implicit conversions
The converting constructor from another basic_json specialization was
always implicit, so a value with a different string_t (std::wstring, a
string with a custom allocator, ...) silently converted into a temporary,
e.g. when passed to a function taking const nlohmann::json&. Such
conversions do not produce correct values (#3425), and
JSON_USE_IMPLICIT_CONVERSIONS=0 did not catch them.
When JSON_USE_IMPLICIT_CONVERSIONS is 0, the constructor is now explicit
if the string types differ. Specializations sharing a string type (json
and ordered_json, different serializers or object maps) stay implicitly
convertible, so the NLOHMANN_DEFINE_TYPE_* macros keep working with
nested json members. get<BasicJsonType>() constructs explicitly and
works in both modes.
Fixes#2649.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
* Construct explicitly in get_to() and to_json(std::optional)
With JSON_USE_IMPLICIT_CONVERSIONS=0 the conversion from a basic_json
with a different string type is now explicit, but two library paths
still assigned such a value implicitly and failed to compile inside the
library:
- get_to() with a basic_json target (the #2175 overload) did
`v = *this`, so json(42).get_to(alt_json&) broke although
get<alt_json>() works.
- to_json(BasicJsonType&, const std::optional<T>&) is constrained on
std::is_constructible (which accepts the explicit constructor) but did
`j = *opt`, so converting a std::optional<alt_json> into a json broke.
Both now construct the value explicitly, as get_impl() already does.
Also replace static_cast<bool>(JSON_USE_IMPLICIT_CONVERSIONS) with a
comparison: clang-tidy's modernize-use-bool-literals rejected the cast
of the integer literal the macro expands to, failing ci_clang_tidy.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
---------
Signed-off-by: Niels Lohmann <mail@nlohmann.me>