diff --git a/doc/mkdocs/docs/api/basic_json/default_object_comparator_t.md b/doc/mkdocs/docs/api/basic_json/default_object_comparator_t.md
new file mode 100644
index 000000000..265a9d385
--- /dev/null
+++ b/doc/mkdocs/docs/api/basic_json/default_object_comparator_t.md
@@ -0,0 +1,18 @@
+# nlohmann::basic_json::default_object_comparator_t
+
+```cpp
+using default_object_comparator_t = std::less; // until C++14
+
+using default_object_comparator_t = std::less<>; // since C++14
+```
+
+The default comparator used by [`object_t`](object_t.md).
+
+Since C++14 a transparent comparator is used which prevents unnecessary string construction.
+
+The actual comparator used depends on [`object_t`](object_t.md) and can be obtained via
+[`object_comparator_t`](object_comparator_t.md).
+
+## Version history
+
+- Added in version 3.11.0.
diff --git a/doc/mkdocs/docs/api/basic_json/index.md b/doc/mkdocs/docs/api/basic_json/index.md
index 286fea2b4..68ac063ff 100644
--- a/doc/mkdocs/docs/api/basic_json/index.md
+++ b/doc/mkdocs/docs/api/basic_json/index.md
@@ -128,6 +128,7 @@ The class satisfies the following concept requirements:
- [**array_t**](array_t.md) - type for arrays
- [**binary_t**](binary_t.md) - type for binary arrays
- [**boolean_t**](boolean_t.md) - type for booleans
+- [**default_object_comparator_t**](default_object_comparator_t.md) - default comparator for objects
- [**number_float_t**](number_float_t.md) - type for numbers (floating-point)
- [**number_integer_t**](number_integer_t.md) - type for numbers (integer)
- [**number_unsigned_t**](number_unsigned_t.md) - type for numbers (unsigned)
diff --git a/doc/mkdocs/docs/api/basic_json/object_comparator_t.md b/doc/mkdocs/docs/api/basic_json/object_comparator_t.md
index e2bc79d05..6c64b6453 100644
--- a/doc/mkdocs/docs/api/basic_json/object_comparator_t.md
+++ b/doc/mkdocs/docs/api/basic_json/object_comparator_t.md
@@ -1,16 +1,16 @@
# nlohmann::basic_json::object_comparator_t
-```cpp
-using object_comparator_t = std::less; // until C++14
-using object_comparator_t = std::less<>; // since C++14
+```cpp
+using object_comparator_t = typename object_t::key_compare;
+// or
+using object_comparator_t = default_object_comparator_t;
```
-The comparator used in [`object_t`](object_t.md).
-
-When C++14 is detected, a transparent comparator is used which, when combined with perfect forwarding on find() and
-count() calls, prevents unnecessary string construction.
+The comparator used by [`object_t`](object_t.md). Defined as `#!cpp typename object_t::key_compare` if available,
+and [`default_object_comparator_t`](default_object_comparator_t.md) otherwise.
## Version history
-- Unknown.
+- Added in version 3.0.0.
+- Changed to be conditionally defined as `#!cpp typename object_t::key_compare` or `default_object_comparator_t` in version 3.11.0.
diff --git a/doc/mkdocs/docs/api/basic_json/object_t.md b/doc/mkdocs/docs/api/basic_json/object_t.md
index d4bea15aa..67b3bb78c 100644
--- a/doc/mkdocs/docs/api/basic_json/object_t.md
+++ b/doc/mkdocs/docs/api/basic_json/object_t.md
@@ -3,7 +3,7 @@
```cpp
using object_t = ObjectType>>;
```
@@ -52,7 +52,7 @@ std::map<
>
```
-See [`object_comparator_t`](object_comparator_t.md) for more information.
+See [`default_object_comparator_t`](default_object_comparator_t.md) for more information.
#### Behavior
diff --git a/doc/mkdocs/mkdocs.yml b/doc/mkdocs/mkdocs.yml
index 59f0ae700..302e827cf 100644
--- a/doc/mkdocs/mkdocs.yml
+++ b/doc/mkdocs/mkdocs.yml
@@ -97,6 +97,7 @@ nav:
- 'count': api/basic_json/count.md
- 'crbegin': api/basic_json/crbegin.md
- 'crend': api/basic_json/crend.md
+ - 'default_object_comparator_t': api/basic_json/default_object_comparator_t.md
- 'diff': api/basic_json/diff.md
- 'dump': api/basic_json/dump.md
- 'emplace': api/basic_json/emplace.md
diff --git a/include/nlohmann/detail/meta/type_traits.hpp b/include/nlohmann/detail/meta/type_traits.hpp
index 376c00a09..c111b5520 100644
--- a/include/nlohmann/detail/meta/type_traits.hpp
+++ b/include/nlohmann/detail/meta/type_traits.hpp
@@ -160,6 +160,24 @@ struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >>
T>::value;
};
+template
+using detect_key_compare = typename T::key_compare;
+
+template
+struct has_key_compare : std::integral_constant::value> {};
+
+// obtains the actual object key comparator
+template
+struct actual_object_comparator
+{
+ using object_t = typename BasicJsonType::object_t;
+ using object_comparator_t = typename BasicJsonType::default_object_comparator_t;
+ using type = typename std::conditional < has_key_compare::value,
+ typename object_t::key_compare, object_comparator_t>::type;
+};
+
+template
+using actual_object_comparator_t = typename actual_object_comparator::type;
///////////////////
// is_ functions //
diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp
index 1a2da8d45..51eb73778 100644
--- a/include/nlohmann/json.hpp
+++ b/include/nlohmann/json.hpp
@@ -350,21 +350,23 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
/// the template arguments passed to class @ref basic_json.
/// @{
- /// @brief object key comparator type
- /// @sa https://json.nlohmann.me/api/basic_json/object_comparator_t/
+ /// @brief default object key comparator type
+ /// The actual object key comparator type (@ref object_comparator_t) may be
+ /// different.
+ /// @sa https://json.nlohmann.me/api/basic_json/default_object_comparator_t/
#if defined(JSON_HAS_CPP_14)
- // Use transparent comparator if possible, combined with perfect forwarding
- // on find() and count() calls prevents unnecessary string construction.
- using object_comparator_t = std::less<>;
+ // use of transparent comparator avoids unnecessary repeated construction of temporaries
+ // in functions involving lookup by key with types other than object_t::key_type (aka. StringType)
+ using default_object_comparator_t = std::less<>;
#else
- using object_comparator_t = std::less;
+ using default_object_comparator_t = std::less;
#endif
/// @brief a type for an object
/// @sa https://json.nlohmann.me/api/basic_json/object_t/
using object_t = ObjectType>>;
@@ -396,6 +398,10 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
/// @sa https://json.nlohmann.me/api/basic_json/binary_t/
using binary_t = nlohmann::byte_container_with_subtype;
+ /// @brief object key comparator type
+ /// @sa https://json.nlohmann.me/api/basic_json/object_comparator_t/
+ using object_comparator_t = detail::actual_object_comparator_t;
+
/// @}
private:
diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp
index e806a8f00..cb48ffe59 100644
--- a/single_include/nlohmann/json.hpp
+++ b/single_include/nlohmann/json.hpp
@@ -3295,6 +3295,24 @@ struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >>
T>::value;
};
+template
+using detect_key_compare = typename T::key_compare;
+
+template
+struct has_key_compare : std::integral_constant::value> {};
+
+// obtains the actual object key comparator
+template
+struct actual_object_comparator
+{
+ using object_t = typename BasicJsonType::object_t;
+ using object_comparator_t = typename BasicJsonType::default_object_comparator_t;
+ using type = typename std::conditional < has_key_compare::value,
+ typename object_t::key_compare, object_comparator_t>::type;
+};
+
+template
+using actual_object_comparator_t = typename actual_object_comparator::type;
///////////////////
// is_ functions //
@@ -17812,21 +17830,23 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
/// the template arguments passed to class @ref basic_json.
/// @{
- /// @brief object key comparator type
- /// @sa https://json.nlohmann.me/api/basic_json/object_comparator_t/
+ /// @brief default object key comparator type
+ /// The actual object key comparator type (@ref object_comparator_t) may be
+ /// different.
+ /// @sa https://json.nlohmann.me/api/basic_json/default_object_comparator_t/
#if defined(JSON_HAS_CPP_14)
- // Use transparent comparator if possible, combined with perfect forwarding
- // on find() and count() calls prevents unnecessary string construction.
- using object_comparator_t = std::less<>;
+ // use of transparent comparator avoids unnecessary repeated construction of temporaries
+ // in functions involving lookup by key with types other than object_t::key_type (aka. StringType)
+ using default_object_comparator_t = std::less<>;
#else
- using object_comparator_t = std::less;
+ using default_object_comparator_t = std::less;
#endif
/// @brief a type for an object
/// @sa https://json.nlohmann.me/api/basic_json/object_t/
using object_t = ObjectType>>;
@@ -17858,6 +17878,10 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
/// @sa https://json.nlohmann.me/api/basic_json/binary_t/
using binary_t = nlohmann::byte_container_with_subtype;
+ /// @brief object key comparator type
+ /// @sa https://json.nlohmann.me/api/basic_json/object_comparator_t/
+ using object_comparator_t = detail::actual_object_comparator_t;
+
/// @}
private: