[pairs] # 22 General utilities library [[utilities]](./#utilities) ## 22.3 Pairs [pairs] ### [22.3.1](#general) General [[pairs.general]](pairs.general) [1](#general-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L737) The library provides a template for heterogeneous pairs of values[.](#general-1.sentence-1) The library also provides a matching function template to simplify their construction and several templates that provide access to pair objects as if they were tuple objects (see [[tuple.helper]](tuple.helper "22.4.7 Tuple helper classes") and [[tuple.elem]](tuple.elem "22.4.8 Element access"))[.](#general-1.sentence-2) ### [22.3.2](#pair) Class template pair [[pairs.pair]](pairs.pair) [🔗](#lib:pair_) namespace std {templatestruct 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); templateconstexpr explicit(*see below*) pair(U1&& x, U2&& y); templateconstexpr explicit(*see below*) pair(pair& p); templateconstexpr explicit(*see below*) pair(const pair& p); templateconstexpr explicit(*see below*) pair(pair&& p); templateconstexpr explicit(*see below*) pair(const pair&& p); template<[*pair-like*](tuple.syn#concept:pair-like "22.4.2 Header synopsis [tuple.syn]") P>constexpr explicit(*see below*) pair(P&& p); templateconstexpr pair(piecewise_construct_t, tuple first_args, tuple second_args); constexpr pair& operator=(const pair& p); constexpr const pair& operator=(const pair& p) const; templateconstexpr pair& operator=(const pair& p); templateconstexpr const pair& operator=(const pair& p) const; constexpr pair& operator=(pair&& p) noexcept(*see below*); constexpr const pair& operator=(pair&& p) const; templateconstexpr pair& operator=(pair&& p); templateconstexpr const pair& operator=(pair&& p) const; template<[*pair-like*](tuple.syn#concept:pair-like "22.4.2 Header synopsis [tuple.syn]") P>constexpr pair& operator=(P&& p); template<[*pair-like*](tuple.syn#concept:pair-like "22.4.2 Header 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 pair(T1, T2) -> pair;} [1](#pair-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[.](#pair-1.sentence-1) [2](#pair-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.6 The constexpr and consteval specifiers"))[.](#pair-2.sentence-1) [3](#pair-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L817) If (is_trivially_destructible_v && is_trivially_destructible_v) is true, then the destructor of pair is trivial[.](#pair-3.sentence-1) [4](#pair-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L821) pair is a structural type ([[temp.param]](temp.param#term.structural.type "13.2 Template parameters")) if T and U are both structural types[.](#pair-4.sentence-1) Two values p1 and p2 of type pair are template-argument-equivalent ([[temp.type]](temp.type "13.6 Type equivalence")) if and only ifp1.first and p2.first are template-argument-equivalent andp1.second and p2.second are template-argument-equivalent[.](#pair-4.sentence-2) [🔗](#lib:pair,constructor) `constexpr explicit(see below) pair(); ` [5](#pair-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L835) *Constraints*: - [(5.1)](#pair-5.1) is_default_constructible_v is true and - [(5.2)](#pair-5.2) is_default_constructible_v is true[.](#pair-5.sentence-1) [6](#pair-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L842) *Effects*: Value-initializes first and second[.](#pair-6.sentence-1) [7](#pair-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[.](#pair-7.sentence-1) [*Note [1](#pair-note-1)*: This behavior can be implemented with a trait that checks whether a const T1& or a const T2& can be initialized with {}[.](#pair-7.sentence-2) — *end note*] [🔗](#lib:pair,constructor_) `constexpr explicit(see below) pair(const T1& x, const T2& y); ` [8](#pair-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L864) *Constraints*: - [(8.1)](#pair-8.1) is_copy_constructible_v is true and - [(8.2)](#pair-8.2) is_copy_constructible_v is true[.](#pair-8.sentence-1) [9](#pair-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L871) *Effects*: Initializes first with x and second with y[.](#pair-9.sentence-1) [10](#pair-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L875) *Remarks*: The expression inside explicit is equivalent to:!is_convertible_v || !is_convertible_v [🔗](#lib:pair,constructor__) `template constexpr explicit(see below) pair(U1&& x, U2&& y); ` [11](#pair-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L889) *Constraints*: - [(11.1)](#pair-11.1) is_constructible_v is true and - [(11.2)](#pair-11.2) is_constructible_v is true[.](#pair-11.sentence-1) [12](#pair-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L896) *Effects*: Initializes first withstd​::​forward(x) and second with std​::​forward(y)[.](#pair-12.sentence-1) [13](#pair-13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L902) *Remarks*: The expression inside explicit is equivalent to:!is_convertible_v || !is_convertible_v This constructor is defined as deleted ifreference_constructs_from_temporary_v is true orreference_constructs_from_temporary_v is true[.](#pair-13.sentence-2) [🔗](#lib:pair,constructor___) `template constexpr explicit(see below) pair(pair& p); template constexpr explicit(see below) pair(const pair& p); template constexpr explicit(see below) pair(pair&& p); template constexpr explicit(see below) pair(const pair&& p); template<[pair-like](tuple.syn#concept:pair-like "22.4.2 Header synopsis [tuple.syn]") P> constexpr explicit(see below) pair(P&& p); ` [14](#pair-14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L925) Let *FWD*(u) be static_cast(u)[.](#pair-14.sentence-1) [15](#pair-15) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L928) *Constraints*: - [(15.1)](#pair-15.1) For the last overload,remove_cvref_t

is not a specialization of ranges​::​subrange, - [(15.2)](#pair-15.2) is_constructible_v(*FWD*(p)))> is true, and - [(15.3)](#pair-15.3) is_constructible_v(*FWD*(p)))> is true[.](#pair-15.sentence-1) [16](#pair-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))[.](#pair-16.sentence-1) [17](#pair-17) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L947) *Remarks*: The expression inside explicit is equivalent to:!is_convertible_v(*FWD*(p))), T1> ||!is_convertible_v(*FWD*(p))), T2> The constructor is defined as deleted ifreference_constructs_from_temporary_v(*FWD*(p)))> || reference_constructs_from_temporary_v(*FWD*(p)))> is true[.](#pair-17.sentence-2) [🔗](#lib:pair,constructor____) `template constexpr pair(piecewise_construct_t, tuple first_args, tuple second_args); ` [18](#pair-18) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L970) *Mandates*: - [(18.1)](#pair-18.1) is_constructible_v is true and - [(18.2)](#pair-18.2) is_constructible_v is true[.](#pair-18.sentence-1) [19](#pair-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[.](#pair-19.sentence-1) (Here, forwarding an element x of type U within a tuple object means callingstd​::​forward(x)[.](#pair-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.2 Class template pair [pairs.pair]")[.](#pair-19.sentence-3) [*Note [2](#pair-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.3 Initializing bases and members"))[.](#pair-19.sentence-4) — *end note*] [🔗](#lib:operator=,pair) `constexpr pair& operator=(const pair& p); ` [20](#pair-20) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1000) *Effects*: Assigns p.first to first and p.second to second[.](#pair-20.sentence-1) [21](#pair-21) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1004) *Returns*: *this[.](#pair-21.sentence-1) [22](#pair-22) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1008) *Remarks*: This operator is defined as deleted unlessis_copy_assignable_v is true andis_copy_assignable_v is true[.](#pair-22.sentence-1) [🔗](#lib:operator=,pair_) `constexpr const pair& operator=(const pair& p) const; ` [23](#pair-23) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1021) *Constraints*: - [(23.1)](#pair-23.1) is_copy_assignable_v is true and - [(23.2)](#pair-23.2) is_copy_assignable_v is true[.](#pair-23.sentence-1) [24](#pair-24) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1030) *Effects*: Assigns p.first to first and p.second to second[.](#pair-24.sentence-1) [25](#pair-25) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1034) *Returns*: *this[.](#pair-25.sentence-1) [🔗](#lib:operator=,pair__) `template constexpr pair& operator=(const pair& p); ` [26](#pair-26) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1045) *Constraints*: - [(26.1)](#pair-26.1) is_assignable_v is true and - [(26.2)](#pair-26.2) is_assignable_v is true[.](#pair-26.sentence-1) [27](#pair-27) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1052) *Effects*: Assigns p.first to first and p.second to second[.](#pair-27.sentence-1) [28](#pair-28) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1056) *Returns*: *this[.](#pair-28.sentence-1) [🔗](#lib:operator=,pair___) `template constexpr const pair& operator=(const pair& p) const; ` [29](#pair-29) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1067) *Constraints*: - [(29.1)](#pair-29.1) is_assignable_v is true, and - [(29.2)](#pair-29.2) is_assignable_v is true[.](#pair-29.sentence-1) [30](#pair-30) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1076) *Effects*: Assigns p.first to first and p.second to second[.](#pair-30.sentence-1) [31](#pair-31) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1080) *Returns*: *this[.](#pair-31.sentence-1) [🔗](#lib:operator=,pair____) `constexpr pair& operator=(pair&& p) noexcept(see below); ` [32](#pair-32) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1091) *Constraints*: - [(32.1)](#pair-32.1) is_move_assignable_v is true and - [(32.2)](#pair-32.2) is_move_assignable_v is true[.](#pair-32.sentence-1) [33](#pair-33) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1098) *Effects*: Assigns std​::​forward(p.first) to first andstd​::​forward(p.second) to second[.](#pair-33.sentence-1) [34](#pair-34) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1103) *Returns*: *this[.](#pair-34.sentence-1) [35](#pair-35) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1107) *Remarks*: The exception specification is equivalent to:is_nothrow_move_assignable_v && is_nothrow_move_assignable_v [🔗](#lib:operator=,pair_____) `constexpr const pair& operator=(pair&& p) const; ` [36](#pair-36) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1121) *Constraints*: - [(36.1)](#pair-36.1) is_assignable_v is true and - [(36.2)](#pair-36.2) is_assignable_v is true[.](#pair-36.sentence-1) [37](#pair-37) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1130) *Effects*: Assigns std​::​forward(p.first) to first andstd​::​forward(p.second) to second[.](#pair-37.sentence-1) [38](#pair-38) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1135) *Returns*: *this[.](#pair-38.sentence-1) [🔗](#lib:operator=,pair______) `template constexpr pair& operator=(pair&& p); ` [39](#pair-39) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1146) *Constraints*: - [(39.1)](#pair-39.1) is_assignable_v is true and - [(39.2)](#pair-39.2) is_assignable_v is true[.](#pair-39.sentence-1) [40](#pair-40) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1153) *Effects*: Assigns std​::​forward(p.first) first andstd​::​forward(p.second) to second[.](#pair-40.sentence-1) [41](#pair-41) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1158) *Returns*: *this[.](#pair-41.sentence-1) [🔗](#lib:operator=,pair_______) `template<[pair-like](tuple.syn#concept:pair-like "22.4.2 Header synopsis [tuple.syn]") P> constexpr pair& operator=(P&& p); ` [42](#pair-42) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1169) *Constraints*: - [(42.1)](#pair-42.1) [*different-from*](range.utility.helpers#concept:different-from "25.5.2 Helper concepts [range.utility.helpers]") ([[range.utility.helpers]](range.utility.helpers "25.5.2 Helper concepts")) is true, - [(42.2)](#pair-42.2) remove_cvref_t

is not a specialization of ranges​::​subrange, - [(42.3)](#pair-42.3) is_assignable_v(std​::​forward

(p)))> is true, and - [(42.4)](#pair-42.4) is_assignable_v(std​::​forward

(p)))> is true[.](#pair-42.sentence-1) [43](#pair-43) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1185) *Effects*: Assigns get<0>(std​::​forward

(p)) to first andget<1>(std​::​forward

(p)) to second[.](#pair-43.sentence-1) [44](#pair-44) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1190) *Returns*: *this[.](#pair-44.sentence-1) [🔗](#lib:operator=,pair________) `template<[pair-like](tuple.syn#concept:pair-like "22.4.2 Header synopsis [tuple.syn]") P> constexpr const pair& operator=(P&& p) const; ` [45](#pair-45) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1201) *Constraints*: - [(45.1)](#pair-45.1) [*different-from*](range.utility.helpers#concept:different-from "25.5.2 Helper concepts [range.utility.helpers]") ([[range.utility.helpers]](range.utility.helpers "25.5.2 Helper concepts")) is true, - [(45.2)](#pair-45.2) remove_cvref_t

is not a specialization of ranges​::​subrange, - [(45.3)](#pair-45.3) is_assignable_v(std​::​forward

(p)))> is true, and - [(45.4)](#pair-45.4) is_assignable_v(std​::​forward

(p)))> is true[.](#pair-45.sentence-1) [46](#pair-46) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1217) *Effects*: Assigns get<0>(std​::​forward

(p)) to first andget<1>(std​::​forward

(p)) to second[.](#pair-46.sentence-1) [47](#pair-47) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1222) *Returns*: *this[.](#pair-47.sentence-1) [🔗](#lib:operator=,pair_________) `template constexpr const pair& operator=(pair&& p) const; ` [48](#pair-48) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1233) *Constraints*: - [(48.1)](#pair-48.1) is_assignable_v is true, and - [(48.2)](#pair-48.2) is_assignable_v is true[.](#pair-48.sentence-1) [49](#pair-49) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1242) *Effects*: Assigns std​::​forward(p.first) to first andstd​::​forward(u.second) to second[.](#pair-49.sentence-1) [50](#pair-50) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1247) *Returns*: *this[.](#pair-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](#pair-51) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1259) *Mandates*: - [(51.1)](#pair-51.1) For the first overload,is_swappable_v is true andis_swappable_v is true[.](#pair-51.1.sentence-1) - [(51.2)](#pair-51.2) For the second overload,is_swappable_v is true andis_swappable_v is true[.](#pair-51.2.sentence-1) [52](#pair-52) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1272) *Preconditions*: first is swappable with ([[swappable.requirements]](swappable.requirements "16.4.4.3 Swappable requirements")) p.first andsecond is swappable with p.second[.](#pair-52.sentence-1) [53](#pair-53) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1277) *Effects*: Swapsfirst with p.first andsecond with p.second[.](#pair-53.sentence-1) [54](#pair-54) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1283) *Remarks*: The exception specification is equivalent to: - [(54.1)](#pair-54.1) is_nothrow_swappable_v && is_nothrow_swappable_v for the first overload, and - [(54.2)](#pair-54.2) is_nothrow_swappable_v && is_nothrow_swappable_v for the second overload[.](#pair-54.sentence-1) ### [22.3.3](#spec) Specialized algorithms [[pairs.spec]](pairs.spec) [🔗](#lib:operator==,pair) `template constexpr bool operator==(const pair& x, const pair& y); ` [1](#spec-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1305) *Constraints*: x.first == y.first and x.second == y.second are valid expressions and each of decltype(x.first == y.first) anddecltype(x.second == y.second) models *boolean- testable*[.](#spec-1.sentence-1) [2](#spec-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1312) *Returns*: x.first == y.first && x.second == y.second[.](#spec-2.sentence-1) [🔗](#lib:operator%3c=%3e,pair) `template constexpr common_comparison_category_t, synth-three-way-result> operator<=>(const pair& x, const pair& y); ` [3](#spec-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1326) *Effects*: Equivalent to:if (auto c = *synth-three-way*(x.first, y.first); c != 0) return c;return *synth-three-way*(x.second, y.second); [🔗](#lib:swap,pair_) `template constexpr void swap(pair& x, pair& y) noexcept(noexcept(x.swap(y))); template constexpr void swap(const pair& x, const pair& y) noexcept(noexcept(x.swap(y))); ` [4](#spec-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1344) *Constraints*: - [(4.1)](#spec-4.1) For the first overload,is_swappable_v is true andis_swappable_v is true[.](#spec-4.1.sentence-1) - [(4.2)](#spec-4.2) For the second overload,is_swappable_v is true andis_swappable_v is true[.](#spec-4.2.sentence-1) [5](#spec-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1357) *Effects*: Equivalent to x.swap(y)[.](#spec-5.sentence-1) [🔗](#lib:make_pair) `template constexpr pair, unwrap_ref_decay_t> make_pair(T1&& x, T2&& y); ` [6](#spec-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1369) *Returns*: pair, unwrap_ref_decay_t>(std::forward(x), std::forward(y)) [7](#spec-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1377) [*Example [1](#spec-example-1)*: In place of:return pair(5, 3.1415926); // explicit types a C++ program may contain:return make_pair(5, 3.1415926); // types are deduced — *end example*] ### [22.3.4](#pair.astuple) Tuple-like access to pair [[pair.astuple]](pair.astuple) [🔗](#lib:tuple_size) `template struct tuple_size> : integral_constant { }; ` [🔗](#lib:tuple_element) `template struct tuple_element> { using type = see below ; }; ` [1](#pair.astuple-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1405) *Mandates*: I<2[.](#pair.astuple-1.sentence-1) [2](#pair.astuple-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1409) *Type*: The type T1 if I is 0, otherwise the type T2[.](#pair.astuple-2.sentence-1) [🔗](#lib:get,pair) `template constexpr tuple_element_t>& get(pair& p) noexcept; template constexpr const tuple_element_t>& get(const pair& p) noexcept; template constexpr tuple_element_t>&& get(pair&& p) noexcept; template constexpr const tuple_element_t>&& get(const pair&& p) noexcept; ` [3](#pair.astuple-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1427) *Mandates*: I<2[.](#pair.astuple-3.sentence-1) [4](#pair.astuple-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1431) *Returns*: - [(4.1)](#pair.astuple-4.1) If I is 0, returns a reference to p.first[.](#pair.astuple-4.1.sentence-1) - [(4.2)](#pair.astuple-4.2) If I is 1, returns a reference to p.second[.](#pair.astuple-4.2.sentence-1) [🔗](#lib:get,pair_) `template constexpr T1& get(pair& p) noexcept; template constexpr const T1& get(const pair& p) noexcept; template constexpr T1&& get(pair&& p) noexcept; template constexpr const T1&& get(const pair&& p) noexcept; ` [5](#pair.astuple-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1455) *Mandates*: T1 and T2 are distinct types[.](#pair.astuple-5.sentence-1) [6](#pair.astuple-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1459) *Returns*: A reference to p.first[.](#pair.astuple-6.sentence-1) [🔗](#lib:get,pair__) `template constexpr T2& get(pair& p) noexcept; template constexpr const T2& get(const pair& p) noexcept; template constexpr T2&& get(pair&& p) noexcept; template constexpr const T2&& get(const pair&& p) noexcept; ` [7](#pair.astuple-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1477) *Mandates*: T1 and T2 are distinct types[.](#pair.astuple-7.sentence-1) [8](#pair.astuple-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1481) *Returns*: A reference to p.second[.](#pair.astuple-8.sentence-1) ### [22.3.5](#pair.piecewise) Piecewise construction [[pair.piecewise]](pair.piecewise) [🔗](#lib:piecewise_construct_t) `struct piecewise_construct_t { explicit piecewise_construct_t() = default; }; inline constexpr piecewise_construct_t piecewise_construct{}; ` [1](#pair.piecewise-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1497) The struct piecewise_construct_t is an empty class type used as a unique type to disambiguate constructor and function overloading[.](#pair.piecewise-1.sentence-1) Specifically,pair has a constructor with piecewise_construct_t as the first argument, immediately followed by two arguments used for piecewise construction of the elements of the pair object[.](#pair.piecewise-1.sentence-2)