[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 {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](#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.6 The 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 && is_trivially_destructible_v) 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 is a structural type ([[temp.param]](temp.param#term.structural.type "13.2 Template parameters")) if T and U are both structural types[.](#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[.](#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 is true and - [(5.2)](#5.2) is_default_constructible_v 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 is true and - [(8.2)](#8.2) is_copy_constructible_v 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 || !is_convertible_v [🔗](#lib:pair,constructor__) `template 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 is true and - [(11.2)](#11.2) is_constructible_v is true[.](#11.sentence-1) [12](#12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L896) *Effects*: Initializes first withstd​::​forward(x) and second with std​::​forward(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 || !is_convertible_v This constructor is defined as deleted ifreference_constructs_from_temporary_v is true orreference_constructs_from_temporary_v is true[.](#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](#14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L925) Let *FWD*(u) be static_cast(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

is not a specialization of ranges​::​subrange, - [(15.2)](#15.2) is_constructible_v(*FWD*(p)))> is true, and - [(15.3)](#15.3) is_constructible_v(*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(*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[.](#17.sentence-2) [🔗](#lib:pair,constructor____) `template constexpr pair(piecewise_construct_t, tuple first_args, tuple second_args); ` [18](#18) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L970) *Mandates*: - [(18.1)](#18.1) is_constructible_v is true and - [(18.2)](#18.2) is_constructible_v 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(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.2 Class 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.3 Initializing 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 is true andis_copy_assignable_v 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 is true and - [(23.2)](#23.2) is_copy_assignable_v 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 constexpr pair& operator=(const pair& p); ` [26](#26) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1045) *Constraints*: - [(26.1)](#26.1) is_assignable_v is true and - [(26.2)](#26.2) is_assignable_v 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 constexpr const pair& operator=(const pair& p) const; ` [29](#29) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1067) *Constraints*: - [(29.1)](#29.1) is_assignable_v is true, and - [(29.2)](#29.2) is_assignable_v 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 is true and - [(32.2)](#32.2) is_move_assignable_v is true[.](#32.sentence-1) [33](#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[.](#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 && is_nothrow_move_assignable_v [🔗](#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 is true and - [(36.2)](#36.2) is_assignable_v is true[.](#36.sentence-1) [37](#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[.](#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 constexpr pair& operator=(pair&& p); ` [39](#39) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1146) *Constraints*: - [(39.1)](#39.1) is_assignable_v is true and - [(39.2)](#39.2) is_assignable_v is true[.](#39.sentence-1) [40](#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[.](#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.2 Header 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.2 Helper concepts [range.utility.helpers]") ([[range.utility.helpers]](range.utility.helpers "25.5.2 Helper concepts")) is true, - [(42.2)](#42.2) remove_cvref_t

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

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

(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)) to first andget<1>(std​::​forward

(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.2 Header 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.2 Helper concepts [range.utility.helpers]") ([[range.utility.helpers]](range.utility.helpers "25.5.2 Helper concepts")) is true, - [(45.2)](#45.2) remove_cvref_t

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

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

(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)) to first andget<1>(std​::​forward

(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 constexpr const pair& operator=(pair&& p) const; ` [48](#48) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1233) *Constraints*: - [(48.1)](#48.1) is_assignable_v is true, and - [(48.2)](#48.2) is_assignable_v is true[.](#48.sentence-1) [49](#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[.](#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 is true andis_swappable_v is true[.](#51.1.sentence-1) - [(51.2)](#51.2) For the second overload,is_swappable_v is true andis_swappable_v 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.3 Swappable 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 && is_nothrow_swappable_v for the first overload, and - [(54.2)](#54.2) is_nothrow_swappable_v && is_nothrow_swappable_v for the second overload[.](#54.sentence-1)