Compare commits

...
Author SHA1 Message Date
Niels Lohmann 54ed6480d5 Fix deprecated json_pointer/string operator== warning in value()
value(KeyType&&, default) is constrained on is_comparable_with_object_key,
which passes KeyType as a reference. is_comparable's dispatch on
is_json_pointer_of<A, B> only matches a json_pointer as a plain type or a
plain reference, so a const-qualified reference (as produced when KeyType
is deduced from a json_pointer argument) fell through to
is_comparable_no_json_pointer, which instantiates the deprecated
json_pointer/string comparison operators. This made ordered_json's
transparent comparator (and any transparent comparator on a custom string
type) warn under -Wdeprecated-declarations when calling
value(json_pointer, default), even though no such comparison is ever
performed. at() was already fixed for this in #5289, which does not use
is_comparable_with_object_key.

Strip references and cv-qualifiers with uncvref_t before the
is_json_pointer_of dispatch, so any reference-to-json_pointer is
recognized regardless of qualifiers.

Fixes #5664.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-09-29 23:17:00 +02:00
3 changed files with 21 additions and 2 deletions
+1 -1
View File
@@ -725,7 +725,7 @@ std::is_constructible <decltype(std::declval<Compare>()(std::declval<A>(), std::
// avoid their instantiation on all compilers, even when the first operand
// is false. The dispatch on is_json_pointer_of can be removed once the
// deprecated json_pointer comparison operators have been removed.
template<typename Compare, typename A, typename B, bool = is_json_pointer_of<A, B>::value>
template<typename Compare, typename A, typename B, bool = is_json_pointer_of<uncvref_t<A>, uncvref_t<B>>::value>
struct is_comparable : std::false_type {};
template<typename Compare, typename A, typename B>
+1 -1
View File
@@ -4735,7 +4735,7 @@ std::is_constructible <decltype(std::declval<Compare>()(std::declval<A>(), std::
// avoid their instantiation on all compilers, even when the first operand
// is false. The dispatch on is_json_pointer_of can be removed once the
// deprecated json_pointer comparison operators have been removed.
template<typename Compare, typename A, typename B, bool = is_json_pointer_of<A, B>::value>
template<typename Compare, typename A, typename B, bool = is_json_pointer_of<uncvref_t<A>, uncvref_t<B>>::value>
struct is_comparable : std::false_type {};
template<typename Compare, typename A, typename B>
+19
View File
@@ -858,6 +858,25 @@ TEST_CASE("JSON pointers")
}
}
SECTION("value(json_pointer, default) with ordered_json #5664")
{
// ordered_json's transparent object comparator made value()'s
// is_comparable_with_object_key check (which passes the pointer as
// a reference) instantiate the deprecated json_pointer/string
// comparison; this must compile without relying on it. The
// deprecation warning itself is not observable here, since the
// unit test build disables -Wdeprecated-declarations (see
// cmake/clang_flags.cmake); it was checked manually instead.
const nlohmann::ordered_json j = {{"n", 1}, {"s", "text"}};
const nlohmann::ordered_json::json_pointer ptr_n("/n");
const nlohmann::ordered_json::json_pointer ptr_s("/s");
const nlohmann::ordered_json::json_pointer ptr_missing("/missing");
CHECK(j.value(ptr_n, 0) == 1);
CHECK(j.value(ptr_s, std::string("x")) == "text");
CHECK(j.value(ptr_missing, 42) == 42);
}
// build with C++20
// JSON_HAS_CPP_20
#if defined(__cpp_char8_t)