mirror of
https://github.com/nlohmann/json.git
synced 2026-07-09 03:55:09 +00:00
Document std::optional<T> direct-init/copy-init limitation with null
Add regression test pinning current behavior (CHECK_THROWS_AS) in the null section of unit-conversions.cpp with detailed comment explaining the C++ language-level cause (std::optional's own converting constructor wins overload resolution over basic_json::operator T()). Add a warning callout in conversions.md documenting that direct construction/ assignment of std::optional<T> from JSON null throws type_error 302, with a clear workaround (use get<std::optional<T>>() or get_to() instead, which correctly produce std::nullopt). This is a limitation at the language level: there is no SFINAE path to distinguish "called from inside std::optional's own constructor" from "direct call", so fixing it would require breaking changes to operator ValueType(). A permanent fix belongs in the 4.0 type-strictness redesign (#3453). Signed-off-by: Niels Lohmann <mail@nlohmann.me> Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -1771,6 +1771,16 @@ TEST_CASE("std::optional")
|
||||
|
||||
CHECK(json(opt_null) == j_null);
|
||||
CHECK(j_null.get<std::optional<std::string>>() == std::nullopt);
|
||||
|
||||
// Constructing std::optional<T> directly from JSON null throws because
|
||||
// std::optional's own converting constructor is chosen over basic_json's
|
||||
// operator T(). This is a language-level limitation (std::optional<T> is
|
||||
// constructible from T, and T is constructible from basic_json via the
|
||||
// operator); there is no SFINAE path that distinguishes "call from inside
|
||||
// std::optional's constructor" from "direct call". Use get<std::optional<T>>()
|
||||
// or get_to() instead for correct null handling. See json#4864 and #XXXX.
|
||||
CHECK_THROWS_AS(std::optional<std::string>(j_null), json::type_error);
|
||||
CHECK_THROWS_AS(std::optional<int>(j_null), json::type_error);
|
||||
}
|
||||
|
||||
SECTION("string")
|
||||
|
||||
Reference in New Issue
Block a user