Accept lvalues in ordered_map::emplace's value parameter

ordered_map::emplace(key, value) took the mapped value only by T&&, an
rvalue reference rather than a forwarding reference, so
ordered_json::emplace("a", value) failed to compile whenever value was
an lvalue or a const lvalue, even though the same call compiles for
json (whose object_t is std::map, with a variadic emplace). Turn the
value parameter into a separately-deduced forwarding reference,
constrained with std::is_constructible so the overloads still only
accept something convertible to the mapped type. std::map-compatible
semantics are unchanged: emplace still does nothing if the key already
exists.

Open PR #5609 also touches ordered_map.hpp (moving values on vector
growth); this change only touches the two emplace() overloads and
should not conflict.

Fixes #5673.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
Niels Lohmann
2026-09-29 23:19:59 +02:00
parent 633de8e44b
commit 989b8ed841
5 changed files with 134 additions and 12 deletions
+9 -6
View File
@@ -25832,7 +25832,9 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
return *this;
}
std::pair<iterator, bool> emplace(const key_type& key, T&& t)
template < class V, detail::enable_if_t <
detail::is_constructible < T, V&& >::value, int > = 0 >
std::pair<iterator, bool> emplace(const key_type& key, V && t)
{
for (auto it = this->begin(); it != this->end(); ++it)
{
@@ -25841,13 +25843,14 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
return {it, false};
}
}
Container::emplace_back(key, std::forward<T>(t));
Container::emplace_back(key, std::forward<V>(t));
return {std::prev(this->end()), true};
}
template<class KeyType, detail::enable_if_t<
detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0>
std::pair<iterator, bool> emplace(KeyType && key, T && t)
template < class KeyType, class V, detail::enable_if_t <
detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value&&
detail::is_constructible < T, V&& >::value, int > = 0 >
std::pair<iterator, bool> emplace(KeyType && key, V && t)
{
for (auto it = this->begin(); it != this->end(); ++it)
{
@@ -25856,7 +25859,7 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
return {it, false};
}
}
Container::emplace_back(std::forward<KeyType>(key), std::forward<T>(t));
Container::emplace_back(std::forward<KeyType>(key), std::forward<V>(t));
return {std::prev(this->end()), true};
}