std::multiset::multiset(3)

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

πŸ’– NAME πŸ’–

okay so bestie, this is the std::multiset::multiset(3) page β€” the constructor glow-up for std::multiset, from the C++ Standard Libary manual (yes, that spelling is in the header 😭). it’s giving β€œevery way to build a multiset,” and we’re covering all of them, no cap.

🌸 Synopsis 🌸

the signature buffet, exactly as printed:

          multiset();
       (until C++11)
          multiset()
       (since C++11)
              : multiset(Compare()) {}
          explicit multiset( const Compare& comp,                           (2)
                             const Allocator& alloc = Allocator() );
          explicit multiset( const Allocator& alloc );                      (3)
       (since C++11)
          template< class InputIt >

          multiset( InputIt first, InputIt last,                            (4)
                    const Compare& comp = Compare(),

                    const Allocator& alloc = Allocator() );
          template< class InputIt >

          multiset( InputIt first, InputIt last,                            (5)
       (since C++14)
                    const Allocator& alloc )

              : multiset(first, last, Compare(), alloc) {}
          multiset( const multiset& other );                                (6)
          multiset( const multiset& other, const Allocator& alloc );        (7)
       (since C++11)
          multiset( multiset&& other );                                     (8)
       (since C++11)
          multiset( multiset&& other, const Allocator& alloc );             (9)
       (since C++11)
          multiset( std::initializer_list<value_type> init,             (1)

                    const Compare& comp = Compare(),
       (10) (since C++11)

                    const Allocator& alloc = Allocator() );
          multiset( std::initializer_list<value_type> init,

                    const Allocator& alloc )
       (11) (since C++14)

              : multiset(init, Compare(), alloc) {}
          template< container-compatible-range<value_type> R >

          multiset( std::from_range_t, R&& rg,
       (12) (since C++23)
                    const Compare& comp = Compare(),

                    const Allocator& alloc = Allocator() );
          template< container-compatible-range<value_type> R >

          multiset( std::from_range_t, R&& rg,
                    const Allocator& alloc )
       (13) (since C++23)

              : multiset(std::from_range, std::forward<R>(rg),
          Compare(), alloc) {}

πŸ’¬ Description πŸ’¬

multiset is constructing a brand-new container from a whole variety of data sources, and optionally using a user-supplied allocator alloc or comparison function object comp. iconic behavior, honestly.

  • 1-3) β€” constructs an empty container.
  • 4,5) β€” constructs the container with the contents of the range [first, last). If [first, last) is not a valid range, the behavior is undefined. ⚠️ not a vibe, fr fr.
  • 6,7) β€” copy constructor. Constructs the container with the copy of the contents of other.

If alloc is not provided, allocator is obtained by calling (since C++11) std::allocator_traits<allocator_type>::select_on_container_copy_construction(other.get_allocator()).

During class template argument deduction, only the first argument contributes to the deduction of the container's Allocator template parameter. (since C++23)

  • 8,9) β€” move constructor. Constructs the container with the contents of other using move semantics. If alloc is not provided, allocator is obtained by move-construction from the allocator belonging to other.

During class template argument deduction, only the first argument contributes to the deduction of the container's Allocator template parameter. (since C++23)

  • 10,11) β€” initializer-list constructor. Constructs the container with the contents of the initializer list init.
  • 12,13) β€” constructs the container with the contents of rg.

πŸŽ€ Parameters πŸŽ€

  • alloc β€” allocator to use for all memory allocations of this container.
  • comp β€” comparison function object to use for all comparisons of keys.
  • first, last β€” the range to copy the elements from.
  • other β€” another container to be used as source to initialize the elements of the container with.
  • init β€” initializer list to initialize the elements of the container with.
  • rg β€” a container compatible range, that is, an input_range whose elements are convertible to value_type.

✨ Type requirements ✨

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

πŸ”₯ Complexity πŸ”₯

  • 1-3) β€” constant.
  • 4,5) β€” NΒ·log(N) where N is std::distance(first, last) in general, linear in N if [first, last) is already sorted by value_comp().
  • 6,7) β€” linear in size of other.
  • 8,9) β€” constant. If alloc is given and alloc != other.get_allocator(), then linear.
  • 10,11) β€” NΒ·log(N) where N is init.size() in general, linear in N if init is already sorted by value_comp().
  • 12,13) β€” NΒ·log(N) where N is ranges::distance(rg) in general, linear in N if rg is already sorted by value_comp().

🫢 Exceptions 🫢

Calls to Allocator::allocate may throw. heads up, bestie.

🌈 Notes 🌈

After container move construction (overload (8,9)), 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 has already put the template parameter Allocator into non-deduced contexts in earlier modes.

⭐ Feature-test macro ⭐

  • __cpp_lib_containers_ranges β€” value 202202L, std (C++23), feature: Ranges-aware construction and insertion; overloads (12,13).

🧚 Example 🧚

// Run this code

#include <iostream>
#include <set>
#include <string_view>

template <typename T>
void println(const std::string_view name, const std::multiset<T>& ms)
{
    std::cout << name << ": ";
    for (const auto& element : ms)
        std::cout << element << ' ';
    std::cout << '\n';
}

int main()
{
    // (1) Default constructor
    std::multiset<int> a;
    a.insert(4);
    a.insert(3);
    a.insert(2);
    a.insert(1);
    println("a", a);

    // (4) Range constructor
    std::multiset<int> b(a.begin(), a.find(3));
    println("b", b);

    // (6) Copy constructor
    std::multiset<int> c(a);
    println("c", c);

    // (8) Move constructor
    std::multiset<int> d(std::move(a));
    println("d", d);

    // (10) Initializer list constructor
    std::multiset<int> e{3, 2, 1, 2, 4, 7, 3};
    println("e", e);

    // (12) Range constructor
    const auto w = {"Ξ±", "Ξ²", "Ξ³", "Ξ΄", "Ξ΄", "Ξ³", "Ξ²", "Ξ±"};
#if __cpp_lib_containers_ranges
    std::multiset<std::string> f(std::from_range, w); // overload (12)
#else
    std::multiset<std::string> f(w.begin(), w.end()); // fallback to (4)
#endif
    println("f", f);
}

🌟 Output 🌟

a: 1 2 3 4
b: 1 2
c: 1 2 3 4
d: 1 2 3 4
e: 1 2 2 3 3 4 7
f: Ξ± Ξ± Ξ² Ξ² Ξ³ Ξ³ Ξ΄ Ξ΄

πŸ’… Defect reports πŸ’…

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

  • DR LWG 2076, applied to C++11 β€” behavior as published: overload (4) conditionally required Key to be CopyInsertable into *this; correct behavior: not required.
  • DR LWG 2193, applied to C++11 β€” behavior as published: the default constructor was explicit; correct behavior: made non-explicit.

πŸ‘‘ See also πŸ‘‘

  • operator= β€” assigns values to the container (public member function).

okay that’s the whole constructor saga, bestie. byeeeeee πŸ’…βœ¨ this page is from http://cppreference.com, version/date 2024.06.10, and it’s the std::multiset::multiset(3) page 🫢

πŸ“¦ where this page comes from