std::flat_map::flat_map(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

πŸ’– NAME πŸ’–

std::flat_map::flat_map(3) from the C++ Standard Libary (that’s the header’s spelling, bestie, we keep it) β€” and the name is std::flat_map::flat_map, aka the constructor crew for std::flat_map. This is part 1 of 2, and it is lowkey a lot, so hydrate before reading. πŸ’…


✨ Synopsis ✨

okay so there are literally 28 overloads, every single one since C++23. The way that constructor list ate, fr fr. Here they are, exactly:

(1) (since C++23)
flat_map()
    : flat_map(key_compare()) { }

(2) (since C++23)
template< class Allocator >
flat_map( const flat_map&, const Allocator& alloc );

(3) (since C++23)
template< class Allocator >
flat_map( flat_map&&, const Allocator& alloc );

(4) (since C++23)
flat_map( key_container_type key_cont, mapped_container_type mapped_cont,
          const key_compare& comp = key_compare() );

(5) (since C++23)
template< class Allocator >
flat_map( const key_container_type& key_cont,
          const mapped_container_type& mapped_cont,
          const Allocator& alloc );

(6) (since C++23)
template< class Allocator >
flat_map( const key_container_type& key_cont,
          const mapped_container_type& mapped_cont,
          const key_compare& comp, const Allocator& alloc );

(7) (since C++23)
flat_map( std::sorted_unique_t, key_container_type key_cont,
          mapped_container_type mapped_cont,
          const key_compare& comp = key_compare() );

(8) (since C++23)
template< class Allocator >
flat_map( std::sorted_unique_t, const key_container_type& key_cont,
          const mapped_container_type& mapped_cont, const Allocator& alloc );

(9) (since C++23)
template< class Allocator >
flat_map( std::sorted_unique_t, const key_container_type& key_cont,
          const mapped_container_type& mapped_cont,
          const key_compare& comp, const Allocator& alloc );

(10) (since C++23)
explicit flat_map( const key_compare& comp )
    : c(), compare(comp) { }

(11) (since C++23)
template< class Allocator >
flat_map( const key_compare& comp, const Allocator& alloc );

(12) (since C++23)
template< class Allocator >
explicit flat_map( const Allocator& alloc );

(13) (since C++23)
template< class InputIter >
flat_map( InputIter first, InputIter last,
          const key_compare& comp = key_compare() )
    : c(), compare(comp);

(14) (since C++23)
template< class InputIter, class Allocator >
flat_map( InputIter first, InputIter last,
          const key_compare& comp, const Allocator& alloc );

(15) (since C++23)
template< class InputIter, class Allocator >
flat_map( InputIter first, InputIter last, const Allocator& alloc );

(16) (since C++23)
template< container-compatible-range<value_type> R >
flat_map( std::from_range_t, R&& rg, const key_compare& comp )
    : flat_map(comp);

(17) (since C++23)
template< container-compatible-range<value_type> R >
flat_map( std::from_range_t fr, R&& rg )
    : flat_map(fr, std::forward<R>(rg), key_compare()) { }

(18) (since C++23)
template< container-compatible-range<value_type> R, class Allocator >
flat_map( std::from_range_t, R&& rg, const Allocator& alloc );

(19) (since C++23)
template< container-compatible-range<value_type> R, class Allocator >
flat_map( std::from_range_t, R&& rg, const key_compare& comp,
          const Allocator& alloc );

(20) (since C++23)
template< class InputIter >
flat_map( std::sorted_unique_t s, InputIter first, InputIter last,
          const key_compare& comp = key_compare() )
    : c(), compare(comp);

(21) (since C++23)
template< class InputIter, class Allocator >
flat_map( std::sorted_unique_t s, InputIter first, InputIter last,
          const key_compare& comp, const Allocator& alloc );

(22) (since C++23)
template< class InputIter, class Allocator >
flat_map( std::sorted_unique_t s, InputIter first, InputIter last,
          const Allocator& alloc );

(23) (since C++23)
flat_map( std::initializer_list<value_type> init,
          const key_compare& comp = key_compare() )
    : flat_map(init.begin(), init.end(), comp) { }

(24) (since C++23)
template< class Allocator >
flat_map( std::initializer_list<value_type> init, const key_compare& comp,
          const Allocator& alloc );

(25) (since C++23)
template< class Allocator >
flat_map( std::initializer_list<value_type> init, const Allocator& alloc );

(26) (since C++23)
flat_map( std::sorted_unique_t s,
          std::initializer_list<value_type> init,
          const key_compare& comp = key_compare() )
    : flat_map(s, init.begin(), init.end(), comp) { }

(27) (since C++23)
template< class Allocator >
flat_map( std::sorted_unique_t s,
          std::initializer_list<value_type> init,
          const key_compare& comp, const Allocator& alloc );

(28) (since C++23)
template< class Allocator >
flat_map( std::sorted_unique_t s,
          std::initializer_list<value_type> init,
          const Allocator& alloc );

Constructs a new container adaptor from a whole buffet of data sources, optionally using a user supplied comparison function object comp and/or allocator alloc. 🫢


  1. A default constructor. Constructs an empty container adaptor.
  2. A copy constructor. Constructs c with the copy of the contents of other.c and compare with other.compare. See allocator usage note below.
  3. A move constructor. Constructs the container adaptor with the contents of other using move semantics. See allocator usage note below.
  4. First, initializes c.keys with std::move(key_cont), c.values with std::move(mapped_cont), and compare with comp. Then sorts the underlying range [begin(), end()) with respect to value_comp(). Finally, erases the duplicate elements as if by:
auto zv = views::zip(c.keys, c.values);
auto it = ranges::unique(zv, key_equiv(compare)).begin();
auto dist = distance(zv.begin(), it);
c.keys.erase(c.keys.begin() + dist, c.keys.end());
c.values.erase(c.values.begin() + dist, c.values.end());.
  1. Same as (4), equivalent to flat_map(key_cont, mapped_cont);. See allocator usage note below.
  2. Same as (4), equivalent to flat_map(key_cont, mapped_cont, comp);. See allocator usage note below.
  3. Initializes c.keys with std::move(key_cont), c.values with std::move(mapped_cont), and compare with comp.
  4. Same as (7), equivalent to flat_map(s, key_cont, mapped_cont);. See allocator usage note below.
  5. Same as (7), equivalent to flat_map(s, key_cont, mapped_cont, comp);. See allocator usage note below.
  6. Constructs an empty container adaptor.

11,12. Constructs an empty container adaptor. See allocator usage note below.

  1. Constructs the container adaptor with the contents of the range [first, last), equivalent to insert(first, last);.

14,15. Same as (13). See allocator usage note below.

  1. Constructs the container adaptor with the contents of the range rg. First, uses (10) as delegating constructor. Then initializes c with the contents of rg as if by insert_range(std::forward<R>(rg));.
  2. Same as (16) using it as delegating constructor.

18,19. Same as (16). See allocator usage note below.

  1. Constructs the underlying containers with the contents of the range [first, last) as if by insert(first, last).

21,22. Same as (20). See allocator usage note below.

  1. An initializer-list constructor. Constructs the underlying container with the contents of the initializer list init, using (13) as delegating constructor.

24,25. Same as (23). See allocator usage note below.

  1. An initializer-list constructor. Constructs the underlying container with the contents of the initializer list init, using (20) as delegating constructor.

27,28. Save as (26) β€” yes, the page says β€œSave”, not β€œSame”, and we are not editing the sacred text. 😭 See allocator usage note below.

Note for overloads (13-15,20-22): If [first, last) is not a valid range, the behavior is undefined. Not me warning you dramatically, but also literally warning you. πŸ’€
Note for overloads (4-6,13-19,23-25): If multiple elements in the range have keys that compare equivalent, it is unspecified which element is inserted (pending LWG2844).

🫢 Parameters 🫢

  • key_cont β€” a container to be used as source to initialize the underlying keys container
  • mapped_cont β€” a container to be used as source to initialize the underlying values container
  • other β€” another flat_map to be used as source to initialize the elements of the underlying containers with
  • alloc β€” an allocator to use for all memory allocations of the underlying containers
  • comp β€” a function object to be used for all comparisons of keys
  • first, last β€” a range to copy the elements from
  • init β€” an initializer list to initialize the elements of the underlying containers with
  • rg β€” a container compatible range (that is, an input_range whose elements are convertible to value_type) to be used as source to initialize the underlying containers
  • fr β€” a disambiguation tag that indicates that the contained member should be range constructed
  • s β€” a disambiguation tag that indicates that the input sequence is sorted with respect to value_comp() and all its elements are unique

πŸ‘‘ Type requirements πŸ‘‘

  • InputIt must meet the requirements of LegacyInputIterator.
  • Compare must meet the requirements of Compare.
  • Allocator must meet the requirements of Allocator.

πŸ’… COMPLEXITY πŸ’…

Okay bestie, here’s the tea on how long each overload takes β€” no cap, every single number matters. β˜•βœ¨

  • 1) Constant. Literally instant vibe. ⚑
  • 2) Linear in size of other. Bigger other, more work. 🫢
  • 3) Same as the corresponding move-constructor of the wrapped container, i.e. constant or linear in size of cont. So it’s giving β€œwhatever the wrapped container’s move-constructor does.” πŸ’…
  • 4-6) Linear in \(\scriptsize N\)N if cont is sorted with respect to value_comp(), otherwise \(\scriptsize \mathcal{O}(N\cdot\log{(N)})\)π“ž(NΒ·log(N)), where \(\scriptsize N\)N is the value of key_cont.size() before this call. 🌸
  • 7-9) Same as the corresponding move-constructor of the wrapped container, i.e. constant or linear in size of cont. πŸŽ€
  • 10-12) Constant. ⭐
  • 13-15) Linear in \(\scriptsize N\)N if the input range [first, last) is sorted with respect to value_comp(), otherwise \(\scriptsize \mathcal{O}(N\cdot\log{(N)})\)π“ž(NΒ·log(N)), where \(\scriptsize N\)N is the value of key_cont.size() before this call. πŸ¦‹
  • 16-19) Linear in \(\scriptsize N\)N if the input range rg is sorted with respect to value_comp(), otherwise \(\scriptsize \mathcal{O}(N\cdot\log{(N)})\)π“ž(NΒ·log(N)), where \(\scriptsize N\)N is the value of key_cont.size() before this call. πŸ’œ
  • 20-22) Linear in size of [first, last). πŸ”₯
  • 23-25) Linear in \(\scriptsize N\)N if the elements of init are sorted with respect to value_comp(), otherwise \(\scriptsize \mathcal{O}(N\cdot\log{(N)})\)π“ž(NΒ·log(N)), where \(\scriptsize N\)N is the value of key_cont.size() before this call. πŸ“
  • 26-28) Linear in size of init. 🌈

😭 EXCEPTIONS 😭

Calls to Allocator::allocate may throw. That’s the whole warning β€” allocate can throw, so keep that in mind, bestie. πŸ’€


πŸ“ NOTES πŸ“

After container move construction (overload (3)), 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. 🫢


πŸŽ€ EXAMPLE πŸŽ€

This section is incomplete Reason: no example

😭 not a single example, bestie β€” it’s giving unfinished homework.


πŸ‘‘ SEE ALSO πŸ‘‘

  • operator= β€” assigns values to the container adaptor (public member function) πŸ’…

🏷️ CATEGORY 🏷️

  • Todo no example

mwah πŸ’‹ this page came from http://cppreference.com, dated 2024.06.10 β€” std::flat_map::flat_map(3), periodt. 🫢✨

πŸ“¦ where this page comes from