std::unorde...nordered_map(3)
πΈ std::unordered_map::unordered_map (3) β C++ Standard Libary πΈ
π·οΈ NAME π·οΈ
std::unordered_map::unordered_map β std::unordered_map::unordered_map
Okay bestie, yes the NAME section is literally the same thing twice. It's giving "I have no original thoughts," but make no mistake: this is the constructor page for std::unordered_map, and it's lowkey iconic. π
π Synopsis π
This synopsis is long and a little chaotic β it's giving caffeinated PDF β but it's just eighteen constructor overloads. Here's the code exactly as the manual page lays it out, line breaks and all, because we do not mess with signatures. π₯
unordered_map()
(since C++11)
: unordered_map(size_type(/* implementation-defined */))
(until C++20)
{}
unordered_map();
(since C++20)
explicit unordered_map( size_type bucket_count,
const Hash& hash = Hash(),
const key_equal& equal = key_equal(), (2)
(since C++11)
const Allocator& alloc = Allocator()
);
unordered_map( size_type bucket_count,
const Allocator& alloc ) (3)
(since C++14)
: unordered_map(bucket_count, Hash(), key_equal(), alloc)
{}
unordered_map( size_type bucket_count,
const Hash& hash,
const Allocator& alloc ) (4)
(since C++14)
: unordered_map(bucket_count, hash, key_equal(), alloc)
{}
explicit unordered_map( const Allocator& alloc ); (5)
(since C++11)
template< class InputIt >
unordered_map( InputIt first, InputIt last,
size_type bucket_count = /*
implementation-defined */, (6)
(since C++11)
const Hash& hash = Hash(),
const key_equal& equal = key_equal(),
const Allocator& alloc = Allocator() );
template< class InputIt >
unordered_map( InputIt first, InputIt last,
size_type bucket_count,
const Allocator& alloc ) (7)
(since C++14)
: unordered_map(first, last,
bucket_count, Hash(), key_equal(), alloc)
{}
template< class InputIt >
unordered_map( InputIt first, InputIt last,
size_type bucket_count,
const Hash& hash, (8)
(since C++14)
const Allocator& alloc )
: unordered_map(first, last,
bucket_count, hash, key_equal(), alloc)
{}
unordered_map( const unordered_map& other ); (9)
(since C++11)
unordered_map( const unordered_map& other, const Allocator& (1)
(10) (since C++11)
alloc );
unordered_map( unordered_map&& other );
(11) (since C++11)
unordered_map( unordered_map&& other, const Allocator& alloc
(12) (since C++11)
);
unordered_map( std::initializer_list<value_type> init,
size_type bucket_count = /*
implementation-defined */,
(13) (since C++11)
const Hash& hash = Hash(),
const key_equal& equal = key_equal(),
const Allocator& alloc = Allocator() );
unordered_map( std::initializer_list<value_type> init,
size_type bucket_count,
const Allocator& alloc )
(14) (since C++14)
: unordered_map(init, bucket_count,
Hash(), key_equal(), alloc) {}
unordered_map( std::initializer_list<value_type> init,
size_type bucket_count,
const Hash& hash,
(15) (since C++14)
const Allocator& alloc )
: unordered_map(init, bucket_count,
hash, key_equal(), alloc) {}
template< container-compatible-range<value_type> R >
unordered_map( std::from_range_t, R&& rg,
size_type bucket_count = /* see description
*/,
(16) (since C++23)
const Hash& hash = Hash(),
const key_equal& equal = key_equal(),
const Allocator& alloc = Allocator() );
template< container-compatible-range<value_type> R >
unordered_map( std::from_range_t, R&& rg,
size_type bucket_count,
const Allocator& alloc )
(17) (since C++23)
: unordered_map(std::from_range, std::forward<R>(rg),
bucket_count, Hash(), key_equal(), alloc)
{}
template< container-compatible-range<value_type> R >
unordered_map( std::from_range_t, R&& rg,
size_type bucket_count,
const Hash& hash,
(18) (since C++23)
const Alloc& alloc )
: unordered_map(std::from_range, std::forward<R>(rg),
bucket_count, hash, key_equal(), alloc)
{}
The numbers in parentheses are the manual's overload labels, and they're your map for the tea below. π«Ά
Okay so the big picture: this constructs a new container from a variety of data sources. Optionally it uses the user-supplied bucket_count as a minimal number of buckets to create, hash as the hash function, equal as the function to compare keys, and alloc as the allocator. β¨
- 1-5) Constructs an empty container. Sets
max_load_factor()to1.0. For the default constructor, the number of buckets is implementation-defined. - 6-8) Constructs the container with the contents of the range
[first, last). Setsmax_load_factor()to1.0. If multiple elements in the range have keys that compare equivalent, it is unspecified which element is inserted (pendingLWG2844). - 9,10) Copy constructor. Constructs the container with a copy of the contents of
other; it also copies the load factor, the predicate, and the hash function. Ifallocis not provided, the allocator is obtained by callingstd::allocator_traits<allocator_type>::select_on_container_copy_construction(other.get_allocator()).(since C++23)The template parameterAllocatoris only deduced from the first argument while used in class template argument deduction.
- 11,12) Move constructor. Constructs the container with the contents of
otherusing move semantics. Ifallocis not provided, the allocator is obtained by move-construction from the allocator belonging toother.(since C++23)The template parameterAllocatoris only deduced from the first argument while used in class template argument deduction.
- 13-15) Initializer-list constructor. Constructs the container with the contents of the initializer list
init, same asunordered_map(init.begin(), init.end()). - 16-18) Constructs the container with the contents of
rg. If multiple elements in the range have keys that compare equivalent, it is unspecified which element is inserted (pendingLWG2844).
π Parameters π
allocβ allocator to use for all memory allocations of this containerbucket_countβ minimal number of buckets to use on initialization. If it is not specified, an implementation-defined default value is usedhashβ hash function to useequalβ comparison function to use for all key comparisons of this containerfirst,lastβ the range[first, last)to copy the elements fromrgβ a container compatible range, that is, aninput_rangewhose elements are convertible tovalue_typeotherβ another container to be used as source to initialize the elements of the container withinitβ initializer list to initialize the elements of the container with
π§ Type requirements π§
InputItmust meet the requirements ofLegacyInputIterator.
π₯ Complexity π₯
- 1-5) Constant.
- 6-8) Average case linear (i.e.
O(N), whereNisstd::distance(first, last)), worst case quadratic, i.e.O(N^2). - 9,10) Linear in size of
other. - 11,12) Constant. If
allocis given andalloc != other.get_allocator(), then linear. - 13-15) Average case
O(N)(Nisstd::size(init)), worst caseO(N^2). - 16-18) Average case
O(N)(Nisranges::distance(rg)), worst caseO(N^2).
π Exceptions π
Calls to Allocator::allocate may throw. π
π Notes π
After container move construction (overload (4)), references, pointers, and iterators (other than the end iterator) to other remain valid, but refer to elements that are now in *this. The current standard makes this guarantee via the blanket statement in [container.reqmts]/67, and a more direct guarantee is under consideration via LWG issue 2321.
Although not formally required until C++23, some implementations have already put the template parameter Allocator into non-deduced contexts in earlier modes.
π Feature-test macro π
__cpp_lib_containers_rangesβ202202Lβ(C++23)β Ranges-aware construction and insertion; overloads(16-18)
β¨ EXAMPLE β¨
okay bestie, this example is literally the full tour β default constructor, list constructor, copy, move, range, custom Key with KeyHash/KeyEqual, a Foo with a std::hash specialization, and even lambdas for the custom hash/equality vibe. it's giving "one file, every constructor mood" and honestly? iconic. π
// Run this code
#include <bitset>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
struct Key
{
std::string first;
std::string second;
};
struct KeyHash
{
std::size_t operator()(const Key& k) const
{
return std::hash<std::string>()(k.first) ^
(std::hash<std::string>()(k.second) << 1);
}
};
struct KeyEqual
{
bool operator()(const Key& lhs, const Key& rhs) const
{
return lhs.first == rhs.first && lhs.second == rhs.second;
}
};
struct Foo
{
Foo(int val_) : val(val_) {}
int val;
bool operator==(const Foo &rhs) const { return val == rhs.val; }
};
template<> struct std::hash<Foo>
{
std::size_t operator()(const Foo &f) const
{
return std::hash<int>{}(f.val);
}
};
int main()
{
// default constructor: empty map
std::unordered_map<std::string, std::string> m1;
// list constructor
std::unordered_map<int, std::string> m2 =
{
{1, "foo"},
{3, "bar"},
{2, "baz"}
};
// copy constructor
std::unordered_map<int, std::string> m3 = m2;
// move constructor
std::unordered_map<int, std::string> m4 = std::move(m2);
// range constructor
std::vector<std::pair<std::bitset<8>, int>> v = {{0x12, 1},
{0x01,-1}};
std::unordered_map<std::bitset<8>, double> m5(v.begin(), v.end());
// Option 1 for a constructor with a custom Key type
// Define the KeyHash and KeyEqual structs and use them in the
template
std::unordered_map<Key, std::string, KeyHash, KeyEqual> m6 =
{
{{"John", "Doe"}, "example"},
{{"Mary", "Sue"}, "another"}
};
// Option 2 for a constructor with a custom Key type.
// Define a const == operator for the class/struct and specialize
std::hash
// structure in the std namespace
std::unordered_map<Foo, std::string> m7 =
{
{Foo(1), "One"}, {2, "Two"}, {3, "Three"}
};
// Option 3: Use lambdas
// Note that the initial bucket count has to be passed to the
constructor
struct Goo { int val; };
auto hash = [](const Goo &g){ return std::hash<int>{}(g.val); };
auto comp = [](const Goo &l, const Goo &r){ return l.val == r.val;
};
std::unordered_map<Goo, double, decltype(hash), decltype(comp)>
m8(10, hash, comp);
}
π©Ή DEFECT REPORTS π©Ή
so these are the behavior-changing defect reports that got applied retroactively to previously published C++ standards β yes, the committee really said "actually, bestie, let's circle back and fix that" after the fact. no cap. π«Ά
LWG 2193β applied to C++11: behavior as published was that the default constructor(1)wasexplicit; correct behavior is that it's non-explicit. slay for implicit construction, I guess π
π SEE ALSO π
operator=β assigns values to the container (public member function)
that's the whole page, babe β source is http://cppreference.com, version/date is 2024.06.10, and the page is std::unorde...nordered_map(3) π¦π mwah, go build something cute with your buckets. β¨
π¦ 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