Reject integral keys for contains(), find(), and count() at compile time (#5705)

j.contains(0), j.find(0), and j.count(0) used to compile: the literal 0 is
a null pointer constant, so it converts to a null const char*, and the
overloads taking const typename object_t::key_type& accepted it by
constructing a std::string from that null pointer, which is undefined
behavior (a crash with both libc++ and libstdc++). value(0, default_value)
had the same problem in C++11, where the object comparator is not
transparent.

Add deleted overloads for integral arguments to contains(), find()
(const and non-const), count(), and value() so that these calls are
compile errors in every supported language mode instead of crashing.
Calls with string, string_view, json_pointer, and size-typed element
access (at(), operator[](), erase()) are unaffected.

Fixes #5657.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
Niels Lohmann
2026-09-30 20:07:45 +02:00
committed by GitHub
parent 5bd766aa50
commit 6ae17630a4
7 changed files with 140 additions and 3 deletions
+7 -1
View File
@@ -40,7 +40,11 @@ Logarithmic in the size of the JSON object.
## Notes
This method always returns `0` when executed on a JSON type that is not an object.
- This method always returns `0` when executed on a JSON type that is not an object.
- Calling this function with an integer argument (for example, `#!cpp count(0)`) does not compile: such an argument
would otherwise implicitly convert to a null `#!cpp const char*` and, from there, cause undefined behavior when
constructing a `#!cpp std::string` for the object key. To check for an array element instead, use [`at`](at.md),
[`operator[]`](operator%5B%5D.md), or compare against [`size`](size.md).
## Examples
@@ -81,3 +85,5 @@ This method always returns `0` when executed on a JSON type that is not an objec
1. Added in version 3.11.0.
2. Added in version 1.0.0. Changed parameter `key` type to `KeyType&&` in version 3.11.0.
3. Deleted overload for integral key types added in version 3.13.0 to reject such calls at compile time instead of
causing undefined behavior at runtime.