deductiongu...ordered_map(3)
π NAME π
okay so the raw NAME line is literally deductionguidesforstd::unordered_map - deductionguidesforstd::unordered_map β yes, it says it twice, iconic behavior. This is the deductiongu...ordered_map(3) page from the C++ Standard Libary manual, and itβs all about the deduction guides for std::unordered_map. bestie, itβs giving template magic with main-character energy. π
β¨
β¨ Synopsis β¨
Defined in header <unordered_map> π¦
(1) β since C++17
template< class InputIt,
class Hash = std::hash<iter_key_t<InputIt>>,
class Pred = std::equal_to<iter_key_t<InputIt>>,
class Alloc = std::allocator<iter_to_alloc_t<InputIt>> >
unordered_map( InputIt, InputIt,
typename /*see below*/::size_type = /*see below*/,
Hash = Hash(), Pred = Pred(), Alloc = Alloc()
)
-> unordered_map<iter_key_t<InputIt>,
iter_val_t<InputIt>,
Hash, Pred, Alloc>;
(2) β since C++17
template< class Key, class T, class Hash = std::hash<Key>,
class Pred = std::equal_to<Key>,
class Alloc = std::allocator<std::pair<const Key, T>> >
unordered_map( std::initializer_list<std::pair<Key, T>>,
typename /*see below*/::size_type = /*see below*/,
Hash = Hash(), Pred = Pred(), Alloc = Alloc()
)
-> unordered_map<Key, T, Hash, Pred, Alloc>;
(3) β since C++17
template< class InputIt, class Alloc >
unordered_map( InputIt, InputIt, typename /*see below*/::size_type, Alloc )
-> unordered_map<iter_key_t<InputIt>,
iter_val_t<InputIt>,
std::hash<iter_key_t<InputIt>>,
std::equal_to<iter_key_t<InputIt>>,
Alloc>;
(4) β since C++17
template< class InputIt, class Alloc >
unordered_map( InputIt, InputIt, Alloc )
-> unordered_map<iter_key_t<InputIt>,
iter_val_t<InputIt>,
std::hash<iter_key_t<InputIt>>,
std::equal_to<iter_key_t<InputIt>>,
Alloc>;
(5) β since C++17
template< class InputIt, class Hash, class Alloc >
unordered_map( InputIt, InputIt, typename /*see below*/::size_type, Hash, Alloc )
-> unordered_map<iter_key_t<InputIt>,
iter_val_t<InputIt>, Hash,
std::equal_to<iter_key_t<InputIt>>,
Alloc>;
(6) β since C++17
template< class Key, class T, typename Alloc >
unordered_map( std::initializer_list<std::pair<Key, T>>,
typename /*see below*/::size_type, Alloc )
-> unordered_map<Key, T, std::hash<Key>,
std::equal_to<Key>, Alloc>;
(7) β since C++17
template< class Key, class T, typename Alloc >
unordered_map( std::initializer_list<std::pair<Key, T>>,
Alloc )
-> unordered_map<Key, T, std::hash<Key>,
std::equal_to<Key>, Alloc>;
(8) β since C++17
template< class Key, class T, class Hash, class Alloc >
unordered_map( std::initializer_list<std::pair<Key, T>>,
typename /*see below*/::size_type, Hash, Alloc )
-> unordered_map<Key, T, Hash, std::equal_to<Key>,
Alloc>;
(9) β since C++23
template< ranges::input_range R,
class Hash = std::hash<range_key_t<R>>,
class Pred = std::equal_to<range_key_t<R>>,
class Alloc = std::allocator<range_to_alloc_t<R>> >
unordered_map( std::from_range_t, R&&,
typename /* see description */::size_type = /* see description */,
Hash = Hash(), Pred = Pred(), Alloc = Alloc()
)
-> unordered_map<range_key_t<R>, range_mapped_t<R>,
Hash, Pred, Alloc>;
(10) β since C++23
template< ranges::input_range R, class Alloc >
unordered_map( std::from_range_t, R&&,
typename /* see description */::size_type, Alloc )
-> unordered_map<range_key_t<R>, range_mapped_t<R>,
std::hash<range_key_t<R>>,
std::equal_to<range_key_t<R>>, Alloc>;
(11) β since C++23
template< ranges::input_range R, class Alloc >
unordered_map( std::from_range_t, R&&, Alloc )
-> unordered_map<range_key_t<R>, range_mapped_t<R>,
std::hash<range_key_t<R>>,
std::equal_to<range_key_t<R>>, Alloc>;
(12) β since C++23
template< ranges::input_range R, class Hash, class Alloc >
unordered_map( std::from_range_t, R&&, typename /* see description */::size_type,
Hash, Alloc )
-> unordered_map<range_key_t<R>, range_mapped_t<R>, Hash,
std::equal_to<range_key_t<R>>, Alloc>;
Exposition-only helper type aliases
iter_val_t <span>β</span> (exposition only*)
template< class InputIter >
using iter_val_t =
typename std::iterator_traits<InputIter>::value_type;
iter_key_t <span>β</span> (exposition only*)
template< class InputIter >
using iter_key_t =
std::remove_const_t< std::tuple_element_t<0, iter_val_t<InputIter>>>;
iter_mapped_t <span>β</span> (exposition only*)
template< class InputIter >
using iter_mapped_t =
std::tuple_element_t<1, iter_val_t<InputIter>>;
iter_to_alloc_t <span>β</span> (exposition only*)
template< class InputIter >
using iter_to_alloc_t =
std::pair<std::add_const_t<tuple_element_t<0, iter_val_t<InputIter>>>,
std::tuple_element_t<1, iter_val_t<InputIter>>>;
range_key_t <span>β</span> (since C++23) (exposition only*)
template< ranges::input_range Range >
using range_key_t =
std::remove_const_t<typename ranges::range_value_t<Range>::first_type>;
range_mapped_t <span>β</span> (since C++23) (exposition only*)
template< ranges::input_range Range >
using range_mapped_t =
typename ranges::range_value_t<Range>::second_type;
range_to_alloc_t <span>β</span> (since C++23) (exposition only*)
template< ranges::input_range Range >
using range_to_alloc_t =
std::pair<std::add_const_t<typename ranges::range_value_t<Range>::first_type>,
typename ranges::range_value_t<Range>::second_type>;
1-8) These deduction guides are provided for unordered_map to allow deduction from an iterator range (overloads (1,3-5)) and std::initializer_list (overloads (2,6-8)). slay π
9-12) These deduction guides are provided for unordered_map to allow deduction from a std::from_range_t tag and an input_range. highkey very C++23 of them. π¦
These overloads participate in overload resolution only if InputIt satisfies LegacyInputIterator, Alloc satisfies Allocator, neither Hash nor Pred satisfy Allocator, and Hash is not an integral type. heads up, thatβs the whole vibe check. π
Note: the extent to which the library determines that a type does not satisfyLegacyInputIteratoris unspecified, except that as a minimum integral types do not qualify as input iterators. Likewise, the extent to which it determines that a type does not satisfyAllocatoris unspecified, except that as a minimum the member typeAlloc::value_typemust exist and the expressionstd::declval<Alloc&>().allocate(std::size_t{})must be well-formed when treated as an unevaluated operand. no cap, thatβs literally the fine print. π
The size_type parameter type in these guides refers to the size_type member type of the type deduced by the deduction guide. iykyk β¨
πΈ Notes πΈ
__cpp_lib_containers_rangesβ value202202L, standard(C++23), feature: βRanges-aware construction and insertion; overloads (9-12)β. periodt π
π Example π
// Run this code
#include <unordered_map>
int main()
{
// std::unordered_map m1 = {{"foo", 1}, {"bar", 2}};
// Error: braced-init-list has no type cannot
// deduce pair<Key, T> from {"foo", 1} or {"bar", 2}
std::unordered_map m1 = {std::pair{"foo", 2}, {"bar", 3}}; // guide #2
std::unordered_map m2(m1.begin(), m1.end()); // guide #1
}
not me rereading the comment that says braced-init-list has no type cannot β bestie, itβs exactly as published, and itβs still giving useful. π«Ά
π¦ Defect reports π¦
The following behavior-changing defect reports were applied retroactively to previously published C++ standards. slay for retroactive fixes. π
- LWG 3025 β applied to C++17. Behavior as published: initializer-list guides take
std::pair<const Key, T>. Correct behavior: usestd::pair<Key, T>. literally the glow-up. β¨
source: http://cppreference.com Β· date/version: 2024.06.10 Β· page: deductiongu...ordered_map(3) β bye bestie, go deduce something cute πππ¦
π¦ where this page comes from
- nixpkgs unstable: stdman 2024.07.05
- opensuse-leap 16.0: stdman 2024.07.05-bp160.1.9 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms