Skip to content

Commit

Permalink
Allow preventing implicit converions to basic_json
Browse files Browse the repository at this point in the history
Previously, `JSON_USE_IMPLICIT_CONVERSIONS` only prevented implicit
conversions _from_ `basic_json` to other types.

With this change, implicit conversions _to_ `basic_json` are also
prevented by that macro.
  • Loading branch information
iFreilicht committed Mar 27, 2024
1 parent 199dea1 commit 7c7f7a8
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 3 deletions.
35 changes: 34 additions & 1 deletion docs/mkdocs/docs/api/basic_json/basic_json.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ basic_json(std::nullptr_t = nullptr) noexcept;

// (3)
template<typename CompatibleType>
basic_json(CompatibleType&& val) noexcept(noexcept(
JSON_EXPLICIT basic_json(CompatibleType&& val) noexcept(noexcept(
JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
std::forward<CompatibleType>(val))));

Expand Down Expand Up @@ -58,6 +58,7 @@ basic_json(basic_json&& other) noexcept;
3. This is a "catch all" constructor for all compatible JSON types; that is, types for which a `to_json()` method
exists. The constructor forwards the parameter `val` to that method (to `json_serializer<U>::to_json` method with
`U = uncvref_t<CompatibleType>`, to be exact).
See [Notes](#notes) for the meaning of `JSON_EXPLICIT`.
Template type `CompatibleType` includes, but is not limited to, the following types:
Expand Down Expand Up @@ -239,6 +240,38 @@ basic_json(basic_json&& other) noexcept;
## Notes
- Overload 3:
!!! note "Definition of `JSON_EXPLICIT`"
By default, `JSON_EXPLICIT` is defined to the empty string, so the signature is:
```cpp
template<typename CompatibleType>
basic_json(CompatibleType&& val)
```
If [`JSON_USE_IMPLICIT_CONVERSIONS`](../macros/json_use_implicit_conversions.md) is set to `0`,
`JSON_EXPLICIT` is defined to `#!cpp explicit`:
```cpp
template<typename CompatibleType>
explicit basic_json(CompatibleType&& val)
```
That is, implicit conversions can be switched off by defining
[`JSON_USE_IMPLICIT_CONVERSIONS`](../macros/json_use_implicit_conversions.md) to `0`.
!!! info "Future behavior change"
Implicit conversions will be switched off by default in the next major release of the library. That is,
`JSON_EXPLICIT` will be set to `#!cpp explicit` by default.
You can prepare existing code by already defining
[`JSON_USE_IMPLICIT_CONVERSIONS`](../macros/json_use_implicit_conversions.md) to `0` and replace any implicit
conversions with explicit calls to [the constructor](../basic_json/basic_json.md) or `static_cast`.
- Overload 5:
!!! note "Empty initializer list"
Expand Down
2 changes: 1 addition & 1 deletion include/nlohmann/json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -832,7 +832,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
typename U = detail::uncvref_t<CompatibleType>,
detail::enable_if_t <
!detail::is_basic_json<U>::value && detail::is_compatible_type<basic_json_t, U>::value, int > = 0 >
basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
JSON_EXPLICIT basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
std::forward<CompatibleType>(val))))
{
Expand Down
2 changes: 1 addition & 1 deletion single_include/nlohmann/json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20135,7 +20135,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
typename U = detail::uncvref_t<CompatibleType>,
detail::enable_if_t <
!detail::is_basic_json<U>::value && detail::is_compatible_type<basic_json_t, U>::value, int > = 0 >
basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
JSON_EXPLICIT basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
std::forward<CompatibleType>(val))))
{
Expand Down

0 comments on commit 7c7f7a8

Please sign in to comment.