From 6d7845d207483adf208ab7fff46aaf29ca90ef39 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Wed, 30 Sep 2026 20:06:59 +0200 Subject: [PATCH] Fix deprecated json_pointer/string operator== warning in value() (#5683) 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 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 --- include/nlohmann/detail/meta/type_traits.hpp | 2 +- single_include/nlohmann/json.hpp | 2 +- tests/src/unit-json_pointer.cpp | 19 +++++++++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/include/nlohmann/detail/meta/type_traits.hpp b/include/nlohmann/detail/meta/type_traits.hpp index 6f8bf2a3d..36573bf6f 100644 --- a/include/nlohmann/detail/meta/type_traits.hpp +++ b/include/nlohmann/detail/meta/type_traits.hpp @@ -725,7 +725,7 @@ std::is_constructible ()(std::declval(), 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::value> +template, uncvref_t>::value> struct is_comparable : std::false_type {}; template diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index f2f8a7ab4..6c98e7a8f 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -4735,7 +4735,7 @@ std::is_constructible ()(std::declval(), 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::value> +template, uncvref_t>::value> struct is_comparable : std::false_type {}; template diff --git a/tests/src/unit-json_pointer.cpp b/tests/src/unit-json_pointer.cpp index 76ae1f79b..86c636c2a 100644 --- a/tests/src/unit-json_pointer.cpp +++ b/tests/src/unit-json_pointer.cpp @@ -878,6 +878,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)