docs: state what the converting constructor does on a string/key mismatch (#6092)
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
1 parent
abab6f2f76
commit
a7b377e9ec
4 files changed
+38
-20
No files matched your search
@@ -93,10 +93,18 @@ basic_json(basic_json&& other) noexcept;
|
||||
The constructor tries to convert the internal `m_value` of the parameter. Each member value (object, array, string,
|
||||
etc.) is serialized via the corresponding `to_json()` overload. For objects and strings, the conversion requires
|
||||
that the *target* `basic_json` type's `object_t::key_type` (or `string_t`) be directly constructible from the
|
||||
*source* type's corresponding member type via `is_constructible`. If this requirement is not met, the conversion
|
||||
does not fail to compile; instead, it silently falls back to the array-conversion path, which represents objects
|
||||
as arrays of `[key, value]` pairs and strings as arrays of character codes. This is a known limitation tracked in
|
||||
[issue #3425](https://github.com/nlohmann/json/issues/3425).
|
||||
*source* type's corresponding member type via `is_constructible`. If this requirement is not met, the result
|
||||
depends on the *source* string type:
|
||||
|
||||
- If it is a range of characters (it has `begin()` and `end()`, as `std::string` does), the conversion falls back to
|
||||
the array-conversion path, which represents objects as arrays of `[key, value]` pairs and strings as arrays of
|
||||
character codes. This result has a different type than the source value, so the constructor's
|
||||
[`JSON_ASSERT`](../macros/json_assert.md) fails; with its default definition, `assert`, the program aborts unless
|
||||
`NDEBUG` is defined, in which case the array is returned.
|
||||
- Otherwise, the conversion does not compile, even though `#!cpp std::is_constructible` reports `#!cpp true`; for
|
||||
example, when converting a `basic_json` whose `string_t` is the `alt_string` of the unit tests to `json`.
|
||||
|
||||
This is a known limitation tracked in [issue #3425](https://github.com/nlohmann/json/issues/3425).
|
||||
|
||||
5. Creates a JSON value of type array or object from the passed initializer list `init`. In case `type_deduction` is
|
||||
`#!cpp true` (default), the type of the JSON value to be created is deducted from the initializer list `init`
|
||||
|
||||
@@ -102,9 +102,12 @@ objects.
|
||||
|
||||
When converting an object from one `basic_json` specialization to another via the
|
||||
[converting constructor](basic_json.md) (overload 4), the target `object_t`'s `key_type` must be
|
||||
directly constructible from the source `basic_json`'s `string_t` type (or more generally, from the
|
||||
source object's key type). If this requirement is not met, the conversion does not fail; instead,
|
||||
the object is silently converted as an array of key-value pairs, which is incorrect. See
|
||||
directly constructible from the source object's key type (with the default `std::map`, the source `basic_json`'s
|
||||
`string_t`). If this requirement is not met and the source string type is a range of characters, the
|
||||
object is converted as an array of key-value pairs, which is incorrect: the converting constructor's
|
||||
[`JSON_ASSERT`](../macros/json_assert.md) fails; with its default definition, `assert`, the program aborts unless
|
||||
`NDEBUG` is defined, in which case the array is returned. If the source string type is not a range of characters, the
|
||||
conversion does not compile at all. See [`basic_json`](basic_json.md) and
|
||||
[issue #3425](https://github.com/nlohmann/json/issues/3425) for details and an example.
|
||||
|
||||
## Examples
|
||||
|
||||
@@ -60,9 +60,11 @@ String values are stored as pointers in a `basic_json` type. That is, for any ac
|
||||
When converting a string value from one `basic_json` specialization to another via the
|
||||
[converting constructor](basic_json.md) (overload 4), the target `string_t` must be directly
|
||||
constructible from the source `basic_json`'s `string_t` type. If this requirement is not met, the
|
||||
conversion does not fail; instead, the string is silently converted as an array of character codes,
|
||||
which is incorrect. See [issue #3425](https://github.com/nlohmann/json/issues/3425) for details
|
||||
and an example.
|
||||
conversion depends on the source string type. If it is a range of characters, the string is converted as an array of
|
||||
character codes, which is incorrect: the converting constructor's [`JSON_ASSERT`](../macros/json_assert.md) fails; with
|
||||
its default definition, `assert`, the program aborts unless `NDEBUG` is defined, in which case the array is returned.
|
||||
If the source string type is not a range of characters, the conversion does not compile at all. See
|
||||
[issue #3425](https://github.com/nlohmann/json/issues/3425) for details and an example.
|
||||
|
||||
## Examples
|
||||
|
||||
|
||||
@@ -28,15 +28,16 @@ Requirements are split into two groups:
|
||||
[`BinaryType`](#binarytype)'s `value_type`, and [`NumberUnsignedType`](#numberintegertype-and-numberunsignedtype)
|
||||
being at least as wide as [`NumberIntegerType`](#numberintegertype-and-numberunsignedtype). The rest are not
|
||||
diagnosed with dedicated error messages, and violating most of them results in a compiler error somewhere inside
|
||||
the library. Four violations are not caught at compile time at all:
|
||||
the library. Four violations are not (always) caught at compile time:
|
||||
|
||||
- A [`StringType`](#stringtype) whose `data()` is not null-terminated compiles and silently misparses numbers
|
||||
stored as a `#!cpp long double` that is not IEEE 754 binary64 (e.g., the 80-bit x87 format), because the lexer
|
||||
hands the buffer to `#!cpp std::strtold`.
|
||||
- A stateful [`AllocatorType`](#allocatortype) compiles and silently ignores its state: allocation, deallocation,
|
||||
and [`get_allocator()`](../../api/basic_json/get_allocator.md) each use a different default-constructed instance.
|
||||
- The two [cross-specialization conversions](#cross-specialization-conversions) below. These abort on an assertion
|
||||
in a normal build, and only fail silently under `#!cpp NDEBUG`.
|
||||
- The two [cross-specialization conversions](#cross-specialization-conversions) below, when the source string type
|
||||
is a range of characters. They compile and fail the `#!cpp JSON_ASSERT`: with its default definition, the program
|
||||
aborts unless `#!cpp NDEBUG` is defined, in which case the wrong result is returned silently.
|
||||
|
||||
## Overview
|
||||
|
||||
@@ -765,14 +766,18 @@ See [`json_base_class_t`](../../api/basic_json/json_base_class_t.md) for an exam
|
||||
## Cross-specialization conversions
|
||||
|
||||
Converting a value from one `basic_json` specialization into another (see the
|
||||
[converting constructor](../../api/basic_json/basic_json.md)) imposes two additional requirements that are not
|
||||
diagnosed at compile time. With assertions enabled they abort on the `#!cpp JSON_ASSERT` at the end of the converting
|
||||
constructor; under `#!cpp NDEBUG` they fail **silently** at runtime:
|
||||
[converting constructor](../../api/basic_json/basic_json.md)) imposes two additional requirements:
|
||||
|
||||
- The target `string_t` must be directly constructible from the source `string_t`. Otherwise the string is converted to
|
||||
an array of character codes.
|
||||
- The target `object_t::key_type` must be directly constructible from the source object's key type. Otherwise the
|
||||
object is converted to an array of key/value pairs.
|
||||
- The target `string_t` must be directly constructible from the source `string_t`.
|
||||
- The target `object_t::key_type` must be directly constructible from the source object's key type.
|
||||
|
||||
If a requirement is not met, the result depends on the source string type. If it is a range of characters (it has
|
||||
`begin()` and `end()`, as `std::string` does), the conversion compiles and then fails the `#!cpp JSON_ASSERT` at the
|
||||
end of the converting constructor: with its default definition, `assert`, the program aborts unless `#!cpp NDEBUG` is
|
||||
defined, in which case it **silently** returns an array (of character codes for a string, of key/value pairs for an
|
||||
object). Otherwise, the conversion does not compile, even though
|
||||
`#!cpp std::is_constructible` reports `#!cpp true`; for example, when converting a `basic_json` whose `string_t` is the
|
||||
`alt_string` of the unit tests to `json`.
|
||||
|
||||
See [issue #3425](https://github.com/nlohmann/json/issues/3425), [`string_t`](../../api/basic_json/string_t.md), and
|
||||
[`object_t`](../../api/basic_json/object_t.md).
|
||||
|
||||
Reference in new issue
Block a user