Files
2025-10-25 03:02:53 +03:00

612 lines
20 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[pairs.pair]
# 22 General utilities library [[utilities]](./#utilities)
## 22.3 Pairs [[pairs]](pairs#pair)
### 22.3.2 Class template pair [pairs.pair]
[🔗](#lib:pair)
namespace std {template<class T1, class T2>struct pair {using first_type = T1; using second_type = T2;
T1 first;
T2 second;
pair(const pair&) = default;
pair(pair&&) = default; constexpr explicit(*see below*) pair(); constexpr explicit(*see below*) pair(const T1& x, const T2& y); template<class U1 = T1, class U2 = T2>constexpr explicit(*see below*) pair(U1&& x, U2&& y); template<class U1, class U2>constexpr explicit(*see below*) pair(pair<U1, U2>& p); template<class U1, class U2>constexpr explicit(*see below*) pair(const pair<U1, U2>& p); template<class U1, class U2>constexpr explicit(*see below*) pair(pair<U1, U2>&& p); template<class U1, class U2>constexpr explicit(*see below*) pair(const pair<U1, U2>&& p); template<[*pair-like*](tuple.syn#concept:pair-like "22.4.2Header <tuple> synopsis[tuple.syn]") P>constexpr explicit(*see below*) pair(P&& p); template<class... Args1, class... Args2>constexpr pair(piecewise_construct_t,
tuple<Args1...> first_args, tuple<Args2...> second_args); constexpr pair& operator=(const pair& p); constexpr const pair& operator=(const pair& p) const; template<class U1, class U2>constexpr pair& operator=(const pair<U1, U2>& p); template<class U1, class U2>constexpr const pair& operator=(const pair<U1, U2>& p) const; constexpr pair& operator=(pair&& p) noexcept(*see below*); constexpr const pair& operator=(pair&& p) const; template<class U1, class U2>constexpr pair& operator=(pair<U1, U2>&& p); template<class U1, class U2>constexpr const pair& operator=(pair<U1, U2>&& p) const; template<[*pair-like*](tuple.syn#concept:pair-like "22.4.2Header <tuple> synopsis[tuple.syn]") P>constexpr pair& operator=(P&& p); template<[*pair-like*](tuple.syn#concept:pair-like "22.4.2Header <tuple> synopsis[tuple.syn]") P>constexpr const pair& operator=(P&& p) const; constexpr void swap(pair& p) noexcept(*see below*); constexpr void swap(const pair& p) const noexcept(*see below*); }; template<class T1, class T2> pair(T1, T2) -> pair<T1, T2>;}
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L806)
Constructors and member functions of pair do not throw exceptions unless one of
the element-wise operations specified to be called for that operation
throws an exception[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L811)
The defaulted move and copy constructor, respectively, of pair is a constexpr function if and only if all required element-wise
initializations for move and copy, respectively,
would be constexpr-suitable ([[dcl.constexpr]](dcl.constexpr "9.2.6The constexpr and consteval specifiers"))[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L817)
If (is_trivially_destructible_v<T1> && is_trivially_destructible_v<T2>) is true, then the destructor of pair is trivial[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L821)
pair<T, U> is a structural type ([[temp.param]](temp.param#term.structural.type "13.2Template parameters"))
if T and U are both structural types[.](#4.sentence-1)
Two values p1 and p2 of type pair<T, U> are template-argument-equivalent ([[temp.type]](temp.type "13.6Type equivalence")) if and only ifp1.first and p2.first are template-argument-equivalent andp1.second and p2.second are template-argument-equivalent[.](#4.sentence-2)
[🔗](#lib:pair,constructor)
`constexpr explicit(see below) pair();
`
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L835)
*Constraints*:
- [(5.1)](#5.1)
is_default_constructible_v<T1> is true and
- [(5.2)](#5.2)
is_default_constructible_v<T2> is true[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L842)
*Effects*: Value-initializes first and second[.](#6.sentence-1)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L846)
*Remarks*: The expression inside explicit evaluates to true if and only if either T1 orT2 is not implicitly default-constructible[.](#7.sentence-1)
[*Note [1](#note-1)*:
This behavior can be implemented with a trait that checks
whether a const T1& or a const T2& can be initialized with {}[.](#7.sentence-2)
— *end note*]
[🔗](#lib:pair,constructor_)
`constexpr explicit(see below) pair(const T1& x, const T2& y);
`
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L864)
*Constraints*:
- [(8.1)](#8.1)
is_copy_constructible_v<T1> is true and
- [(8.2)](#8.2)
is_copy_constructible_v<T2> is true[.](#8.sentence-1)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L871)
*Effects*: Initializes first with x and second with y[.](#9.sentence-1)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L875)
*Remarks*: The expression inside explicit is equivalent to:!is_convertible_v<const T1&, T1> || !is_convertible_v<const T2&, T2>
[🔗](#lib:pair,constructor__)
`template<class U1 = T1, class U2 = T2> constexpr explicit(see below) pair(U1&& x, U2&& y);
`
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L889)
*Constraints*:
- [(11.1)](#11.1)
is_constructible_v<T1, U1> is true and
- [(11.2)](#11.2)
is_constructible_v<T2, U2> is true[.](#11.sentence-1)
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L896)
*Effects*: Initializes first withstd::forward<U1>(x) and second with std::forward<U2>(y)[.](#12.sentence-1)
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L902)
*Remarks*: The expression inside explicit is equivalent to:!is_convertible_v<U1, T1> || !is_convertible_v<U2, T2>
This constructor is defined as deleted ifreference_constructs_from_temporary_v<first_type, U1&&> is true orreference_constructs_from_temporary_v<second_type, U2&&> is true[.](#13.sentence-2)
[🔗](#lib:pair,constructor___)
`template<class U1, class U2> constexpr explicit(see below) pair(pair<U1, U2>& p);
template<class U1, class U2> constexpr explicit(see below) pair(const pair<U1, U2>& p);
template<class U1, class U2> constexpr explicit(see below) pair(pair<U1, U2>&& p);
template<class U1, class U2> constexpr explicit(see below) pair(const pair<U1, U2>&& p);
template<[pair-like](tuple.syn#concept:pair-like "22.4.2Header <tuple> synopsis[tuple.syn]") P> constexpr explicit(see below) pair(P&& p);
`
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L925)
Let *FWD*(u) be static_cast<decltype(u)>(u)[.](#14.sentence-1)
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L928)
*Constraints*:
- [(15.1)](#15.1)
For the last overload,remove_cvref_t<P> is not a specialization of ranges::subrange,
- [(15.2)](#15.2)
is_constructible_v<T1, decltype(get<0>(*FWD*(p)))> is true, and
- [(15.3)](#15.3)
is_constructible_v<T2, decltype(get<1>(*FWD*(p)))> is true[.](#15.sentence-1)
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L942)
*Effects*: Initializes first with get<0>(*FWD*(p)) andsecond with get<1>(*FWD*(p))[.](#16.sentence-1)
[17](#17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L947)
*Remarks*: The expression inside explicit is equivalent to:!is_convertible_v<decltype(get<0>(*FWD*(p))), T1> ||!is_convertible_v<decltype(get<1>(*FWD*(p))), T2>
The constructor is defined as deleted ifreference_constructs_from_temporary_v<first_type, decltype(get<0>(*FWD*(p)))> || reference_constructs_from_temporary_v<second_type, decltype(get<1>(*FWD*(p)))> is true[.](#17.sentence-2)
[🔗](#lib:pair,constructor____)
`template<class... Args1, class... Args2>
constexpr pair(piecewise_construct_t,
tuple<Args1...> first_args, tuple<Args2...> second_args);
`
[18](#18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L970)
*Mandates*:
- [(18.1)](#18.1)
is_constructible_v<T1, Args1...> is true and
- [(18.2)](#18.2)
is_constructible_v<T2, Args2...> is true[.](#18.sentence-1)
[19](#19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L977)
*Effects*: Initializes first with arguments of typesArgs1... obtained by forwarding the elements of first_args and initializes second with arguments of types Args2... obtained by forwarding the elements of second_args[.](#19.sentence-1)
(Here, forwarding
an element x of type U within a tuple object means callingstd::forward<U>(x)[.](#19.sentence-2))
This form of construction, whereby constructor
arguments for first and second are each provided in a separatetuple object, is called [*piecewise construction*](#def:piecewise_construction "22.3.2Class template pair[pairs.pair]")[.](#19.sentence-3)
[*Note [2](#note-2)*:
If a data member of pair is of reference type and
its initialization binds it to a temporary object,
the program is ill-formed ([[class.base.init]](class.base.init "11.9.3Initializing bases and members"))[.](#19.sentence-4)
— *end note*]
[🔗](#lib:operator=,pair)
`constexpr pair& operator=(const pair& p);
`
[20](#20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1000)
*Effects*: Assigns p.first to first and p.second to second[.](#20.sentence-1)
[21](#21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1004)
*Returns*: *this[.](#21.sentence-1)
[22](#22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1008)
*Remarks*: This operator is defined as deleted unlessis_copy_assignable_v<T1> is true andis_copy_assignable_v<T2> is true[.](#22.sentence-1)
[🔗](#lib:operator=,pair_)
`constexpr const pair& operator=(const pair& p) const;
`
[23](#23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1021)
*Constraints*:
- [(23.1)](#23.1)
is_copy_assignable_v<const T1> is true and
- [(23.2)](#23.2)
is_copy_assignable_v<const T2> is true[.](#23.sentence-1)
[24](#24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1030)
*Effects*: Assigns p.first to first and p.second to second[.](#24.sentence-1)
[25](#25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1034)
*Returns*: *this[.](#25.sentence-1)
[🔗](#lib:operator=,pair__)
`template<class U1, class U2> constexpr pair& operator=(const pair<U1, U2>& p);
`
[26](#26)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1045)
*Constraints*:
- [(26.1)](#26.1)
is_assignable_v<T1&, const U1&> is true and
- [(26.2)](#26.2)
is_assignable_v<T2&, const U2&> is true[.](#26.sentence-1)
[27](#27)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1052)
*Effects*: Assigns p.first to first and p.second to second[.](#27.sentence-1)
[28](#28)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1056)
*Returns*: *this[.](#28.sentence-1)
[🔗](#lib:operator=,pair___)
`template<class U1, class U2> constexpr const pair& operator=(const pair<U1, U2>& p) const;
`
[29](#29)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1067)
*Constraints*:
- [(29.1)](#29.1)
is_assignable_v<const T1&, const U1&> is true, and
- [(29.2)](#29.2)
is_assignable_v<const T2&, const U2&> is true[.](#29.sentence-1)
[30](#30)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1076)
*Effects*: Assigns p.first to first and p.second to second[.](#30.sentence-1)
[31](#31)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1080)
*Returns*: *this[.](#31.sentence-1)
[🔗](#lib:operator=,pair____)
`constexpr pair& operator=(pair&& p) noexcept(see below);
`
[32](#32)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1091)
*Constraints*:
- [(32.1)](#32.1)
is_move_assignable_v<T1> is true and
- [(32.2)](#32.2)
is_move_assignable_v<T2> is true[.](#32.sentence-1)
[33](#33)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1098)
*Effects*: Assigns std::forward<T1>(p.first) to first andstd::forward<T2>(p.second) to second[.](#33.sentence-1)
[34](#34)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1103)
*Returns*: *this[.](#34.sentence-1)
[35](#35)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1107)
*Remarks*: The exception specification is equivalent to:is_nothrow_move_assignable_v<T1> && is_nothrow_move_assignable_v<T2>
[🔗](#lib:operator=,pair_____)
`constexpr const pair& operator=(pair&& p) const;
`
[36](#36)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1121)
*Constraints*:
- [(36.1)](#36.1)
is_assignable_v<const T1&, T1> is true and
- [(36.2)](#36.2)
is_assignable_v<const T2&, T2> is true[.](#36.sentence-1)
[37](#37)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1130)
*Effects*: Assigns std::forward<T1>(p.first) to first andstd::forward<T2>(p.second) to second[.](#37.sentence-1)
[38](#38)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1135)
*Returns*: *this[.](#38.sentence-1)
[🔗](#lib:operator=,pair______)
`template<class U1, class U2> constexpr pair& operator=(pair<U1, U2>&& p);
`
[39](#39)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1146)
*Constraints*:
- [(39.1)](#39.1)
is_assignable_v<T1&, U1> is true and
- [(39.2)](#39.2)
is_assignable_v<T2&, U2> is true[.](#39.sentence-1)
[40](#40)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1153)
*Effects*: Assigns std::forward<U1>(p.first) first andstd::forward<U2>(p.second) to second[.](#40.sentence-1)
[41](#41)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1158)
*Returns*: *this[.](#41.sentence-1)
[🔗](#lib:operator=,pair_______)
`template<[pair-like](tuple.syn#concept:pair-like "22.4.2Header <tuple> synopsis[tuple.syn]") P> constexpr pair& operator=(P&& p);
`
[42](#42)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1169)
*Constraints*:
- [(42.1)](#42.1)
[*different-from*](range.utility.helpers#concept:different-from "25.5.2Helper concepts[range.utility.helpers]")<P, pair> ([[range.utility.helpers]](range.utility.helpers "25.5.2Helper concepts"))
is true,
- [(42.2)](#42.2)
remove_cvref_t<P> is not a specialization of ranges::subrange,
- [(42.3)](#42.3)
is_assignable_v<T1&, decltype(get<0>(std::forward<P>(p)))> is true, and
- [(42.4)](#42.4)
is_assignable_v<T2&, decltype(get<1>(std::forward<P>(p)))> is true[.](#42.sentence-1)
[43](#43)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1185)
*Effects*: Assigns get<0>(std::forward<P>(p)) to first andget<1>(std::forward<P>(p)) to second[.](#43.sentence-1)
[44](#44)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1190)
*Returns*: *this[.](#44.sentence-1)
[🔗](#lib:operator=,pair________)
`template<[pair-like](tuple.syn#concept:pair-like "22.4.2Header <tuple> synopsis[tuple.syn]") P> constexpr const pair& operator=(P&& p) const;
`
[45](#45)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1201)
*Constraints*:
- [(45.1)](#45.1)
[*different-from*](range.utility.helpers#concept:different-from "25.5.2Helper concepts[range.utility.helpers]")<P, pair> ([[range.utility.helpers]](range.utility.helpers "25.5.2Helper concepts"))
is true,
- [(45.2)](#45.2)
remove_cvref_t<P> is not a specialization of ranges::subrange,
- [(45.3)](#45.3)
is_assignable_v<const T1&, decltype(get<0>(std::forward<P>(p)))> is true, and
- [(45.4)](#45.4)
is_assignable_v<const T2&, decltype(get<1>(std::forward<P>(p)))> is true[.](#45.sentence-1)
[46](#46)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1217)
*Effects*: Assigns get<0>(std::forward<P>(p)) to first andget<1>(std::forward<P>(p)) to second[.](#46.sentence-1)
[47](#47)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1222)
*Returns*: *this[.](#47.sentence-1)
[🔗](#lib:operator=,pair_________)
`template<class U1, class U2> constexpr const pair& operator=(pair<U1, U2>&& p) const;
`
[48](#48)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1233)
*Constraints*:
- [(48.1)](#48.1)
is_assignable_v<const T1&, U1> is true, and
- [(48.2)](#48.2)
is_assignable_v<const T2&, U2> is true[.](#48.sentence-1)
[49](#49)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1242)
*Effects*: Assigns std::forward<U1>(p.first) to first andstd::forward<U2>(u.second) to second[.](#49.sentence-1)
[50](#50)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1247)
*Returns*: *this[.](#50.sentence-1)
[🔗](#lib:swap,pair)
`constexpr void swap(pair& p) noexcept(see below);
constexpr void swap(const pair& p) const noexcept(see below);
`
[51](#51)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1259)
*Mandates*:
- [(51.1)](#51.1)
For the first overload,is_swappable_v<T1> is true andis_swappable_v<T2> is true[.](#51.1.sentence-1)
- [(51.2)](#51.2)
For the second overload,is_swappable_v<const T1> is true andis_swappable_v<const T2> is true[.](#51.2.sentence-1)
[52](#52)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1272)
*Preconditions*: first is swappable with ([[swappable.requirements]](swappable.requirements "16.4.4.3Swappable requirements")) p.first andsecond is swappable with p.second[.](#52.sentence-1)
[53](#53)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1277)
*Effects*: Swapsfirst with p.first andsecond with p.second[.](#53.sentence-1)
[54](#54)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1283)
*Remarks*: The exception specification is equivalent to:
- [(54.1)](#54.1)
is_nothrow_swappable_v<T1> && is_nothrow_swappable_v<T2> for the first overload, and
- [(54.2)](#54.2)
is_nothrow_swappable_v<const T1> && is_nothrow_swappable_v<const T2> for the second overload[.](#54.sentence-1)