diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index 656ec2238..95f5a1dc8 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -3354,21 +3354,22 @@ public: } /// @brief key as it is passed to detail::concat for an error message - /// @note string_t is used where it can be constructed from the key; other - /// key types are passed through unchanged, as concat only needs - /// data() and size() of them - template::value, int> = 0> - static string_t key_for_message(const KeyType& key) - { - return string_t(key); - } - - template < typename KeyType, detail::enable_if_t < !std::is_constructible::value, int > = 0 > + /// @note keys with data() and size() (such as string_t itself or a string + /// view) are passed through unchanged, so a miss does not copy them; + /// other keys (such as string literals or key types that only convert + /// to string_t) are converted to string_t + template < typename KeyType, detail::enable_if_t < detail::detect_string_can_append_data::value, int > = 0 > static const KeyType & key_for_message(const KeyType& key) { return key; // NOLINT(bugprone-return-const-ref-from-parameter): the result is only passed to concat() within the full-expression that holds key } + template < typename KeyType, detail::enable_if_t < !detail::detect_string_can_append_data::value, int > = 0 > + static string_t key_for_message(const KeyType& key) + { + return string_t(key); + } + /// @brief checked array element access used by the at() overloads taking an index /// @throw type_error.304 if @a j is not an array /// @throw out_of_range.401 if @a idx is out of range diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 4a2919bb6..1ea0c0a8e 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -31265,21 +31265,22 @@ public: } /// @brief key as it is passed to detail::concat for an error message - /// @note string_t is used where it can be constructed from the key; other - /// key types are passed through unchanged, as concat only needs - /// data() and size() of them - template::value, int> = 0> - static string_t key_for_message(const KeyType& key) - { - return string_t(key); - } - - template < typename KeyType, detail::enable_if_t < !std::is_constructible::value, int > = 0 > + /// @note keys with data() and size() (such as string_t itself or a string + /// view) are passed through unchanged, so a miss does not copy them; + /// other keys (such as string literals or key types that only convert + /// to string_t) are converted to string_t + template < typename KeyType, detail::enable_if_t < detail::detect_string_can_append_data::value, int > = 0 > static const KeyType & key_for_message(const KeyType& key) { return key; // NOLINT(bugprone-return-const-ref-from-parameter): the result is only passed to concat() within the full-expression that holds key } + template < typename KeyType, detail::enable_if_t < !detail::detect_string_can_append_data::value, int > = 0 > + static string_t key_for_message(const KeyType& key) + { + return string_t(key); + } + /// @brief checked array element access used by the at() overloads taking an index /// @throw type_error.304 if @a j is not an array /// @throw out_of_range.401 if @a idx is out of range