The library provides a template for heterogeneous pairs of values. 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] and [tuple.elem]).
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; EXPLICIT constexpr pair(); EXPLICIT constexpr pair(const T1& x, const T2& y); template<class U1, class U2> EXPLICIT constexpr pair(U1&& x, U2&& y); template<class U1, class U2> EXPLICIT constexpr pair(const pair<U1, U2>& p); template<class U1, class U2> EXPLICIT constexpr pair(pair<U1, U2>&& p); template <class... Args1, class... Args2> pair(piecewise_construct_t, tuple<Args1...> first_args, tuple<Args2...> second_args); pair& operator=(const pair& p); template<class U1, class U2> pair& operator=(const pair<U1, U2>& p); pair& operator=(pair&& p) noexcept(see below); template<class U1, class U2> pair& operator=(pair<U1, U2>&& p); void swap(pair& p) noexcept(see below); }; template<class T1, class T2> pair(T1, T2) -> pair<T1, T2>; }
Constructors and member functions of pair shall not throw exceptions unless one of the element-wise operations specified to be called for that operation throws an exception.
The defaulted move and copy constructor, respectively, of pair shall be a constexpr function if and only if all required element-wise initializations for copy and move, respectively, would satisfy the requirements for a constexpr function. The destructor of pair shall be a trivial destructor if (is_trivially_destructible_v<T1> && is_trivially_destructible_v<T2>) is true.
EXPLICIT constexpr pair();
Remarks: This constructor shall not participate in overload resolution unless is_default_constructible_v<first_type> is true and is_default_constructible_v<second_type> is true. [ Note: This behavior can be implemented by a constructor template with default template arguments. — end note ] The constructor is explicit if and only if either first_type or second_type is not implicitly default-constructible. [ Note: This behavior can be implemented with a trait that checks whether a const first_type& or a const second_type& can be initialized with {}. — end note ]
EXPLICIT constexpr pair(const T1& x, const T2& y);
Remarks: This constructor shall not participate in overload resolution unless is_copy_constructible_v<first_type> is true and is_copy_constructible_v<second_type> is true. The constructor is explicit if and only if is_convertible_v<const first_type&, first_type> is false or is_convertible_v<const second_type&, second_type> is false.
template<class U1, class U2> EXPLICIT constexpr pair(U1&& x, U2&& y);
Remarks: This constructor shall not participate in overload resolution unless is_constructible_v<first_type, U1&&> is true and is_constructible_v<second_type, U2&&> is true. The constructor is explicit if and only if is_convertible_v<U1&&, first_type> is false or is_convertible_v<U2&&, second_type> is false.
template<class U1, class U2> EXPLICIT constexpr pair(const pair<U1, U2>& p);
Remarks: This constructor shall not participate in overload resolution unless is_constructible_v<first_type, const U1&> is true and is_constructible_v<second_type, const U2&> is true. The constructor is explicit if and only if is_convertible_v<const U1&, first_type> is false or is_convertible_v<const U2&, second_type> is false.
template<class U1, class U2> EXPLICIT constexpr pair(pair<U1, U2>&& p);
Effects: Initializes first with std::forward<U1>(p.first) and second with std::forward<U2>(p.second).
Remarks: This constructor shall not participate in overload resolution unless is_constructible_v<first_type, U1&&> is true and is_constructible_v<second_type, U2&&> is true. The constructor is explicit if and only if is_convertible_v<U1&&, first_type> is false or is_convertible_v<U2&&, second_type> is false.
template<class... Args1, class... Args2>
pair(piecewise_construct_t, tuple<Args1...> first_args, tuple<Args2...> second_args);
Requires: is_constructible_v<first_type, Args1&&...> is true and is_constructible_v<second_type, Args2&&...> is true.
Effects: Initializes first with arguments of types Args1... obtained by forwarding the elements of first_args and initializes second with arguments of types Args2... obtained by forwarding the elements of second_args. (Here, forwarding an element x of type U within a tuple object means calling std::forward<U>(x).) This form of construction, whereby constructor arguments for first and second are each provided in a separate tuple object, is called piecewise construction.
pair& operator=(const pair& p);
Remarks: This operator shall be defined as deleted unless is_copy_assignable_v<first_type> is true and is_copy_assignable_v<second_type> is true.
template<class U1, class U2> pair& operator=(const pair<U1, U2>& p);
Remarks: This operator shall not participate in overload resolution unless is_assignable_v<first_type&, const U1&> is true and is_assignable_v<second_type&, const U2&> is true.
pair& operator=(pair&& p) noexcept(see below);
Effects:
Assigns to first with std::forward<first_type>(p.first)
and to second with
std::forward<second_type>(p.second).
Remarks: This operator shall be defined as deleted unless is_move_assignable_v<first_type> is true and is_move_assignable_v<second_type> is true.
Remarks: The expression inside noexcept is equivalent to:
is_nothrow_move_assignable_v<T1> && is_nothrow_move_assignable_v<T2>
template<class U1, class U2> pair& operator=(pair<U1, U2>&& p);
Effects:
Assigns to first with std::forward<U>(p.first)
and to second with
std::forward<V>(p.second).
Remarks: This operator shall not participate in overload resolution unless is_assignable_v<first_type&, U1&&> is true and is_assignable_v<second_type&, U2&&> is true.
void swap(pair& p) noexcept(see below);
Requires: first shall be swappable with p.first and second shall be swappable with p.second.
template <class T1, class T2>
constexpr bool operator==(const pair<T1, T2>& x, const pair<T1, T2>& y);
template <class T1, class T2>
constexpr bool operator<(const pair<T1, T2>& x, const pair<T1, T2>& y);
template <class T1, class T2>
constexpr bool operator!=(const pair<T1, T2>& x, const pair<T1, T2>& y);
template <class T1, class T2>
constexpr bool operator>(const pair<T1, T2>& x, const pair<T1, T2>& y);
template <class T1, class T2>
constexpr bool operator>=(const pair<T1, T2>& x, const pair<T1, T2>& y);
template <class T1, class T2>
constexpr bool operator<=(const pair<T1, T2>& x, const pair<T1, T2>& y);
template<class T1, class T2> void swap(pair<T1, T2>& x, pair<T1, T2>& y)
noexcept(noexcept(x.swap(y)));
Remarks: This function shall not participate in overload resolution unless is_swappable_v<T1> is true and is_swappable_v<T2> is true.
template <class T1, class T2>
constexpr pair<V1, V2> make_pair(T1&& x, T2&& y);
Returns: pair<V1, V2>(std::forward<T1>(x), std::forward<T2>(y)), where V1 and V2 are determined as follows: Let Ui be decay_t<Ti> for each Ti. If Ui is a specialization of reference_wrapper, then Vi is Ui::type&, otherwise Vi is Ui.
template <class T1, class T2>
struct tuple_size<pair<T1, T2>> : integral_constant<size_t, 2> { };
tuple_element<0, pair<T1, T2>>::type
tuple_element<1, pair<T1, T2>>::type
template<size_t I, class T1, class T2>
constexpr tuple_element_t<I, pair<T1, T2>>& get(pair<T1, T2>& p) noexcept;
template<size_t I, class T1, class T2>
constexpr const tuple_element_t<I, pair<T1, T2>>& get(const pair<T1, T2>& p) noexcept;
template<size_t I, class T1, class T2>
constexpr tuple_element_t<I, pair<T1, T2>>&& get(pair<T1, T2>&& p) noexcept;
template<size_t I, class T1, class T2>
constexpr const tuple_element_t<I, pair<T1, T2>>&& get(const pair<T1, T2>&& p) noexcept;
Returns: If I == 0 returns a reference to p.first; if I == 1 returns a reference to p.second; otherwise the program is ill-formed.
template <class T1, class T2>
constexpr T1& get(pair<T1, T2>& p) noexcept;
template <class T1, class T2>
constexpr const T1& get(const pair<T1, T2>& p) noexcept;
template <class T1, class T2>
constexpr T1&& get(pair<T1, T2>&& p) noexcept;
template <class T1, class T2>
constexpr const T1&& get(const pair<T1, T2>&& p) noexcept;
template <class T2, class T1>
constexpr T2& get(pair<T1, T2>& p) noexcept;
template <class T2, class T1>
constexpr const T2& get(const pair<T1, T2>& p) noexcept;
template <class T2, class T1>
constexpr T2&& get(pair<T1, T2>&& p) noexcept;
template <class T2, class T1>
constexpr const T2&& get(const pair<T1, T2>&& p) noexcept;
struct piecewise_construct_t {
explicit piecewise_construct_t() = default;
};
inline constexpr piecewise_construct_t piecewise_construct{};
The struct piecewise_construct_t is an empty structure type used as a unique type to disambiguate constructor and function overloading. Specifically, pair has a constructor with piecewise_construct_t as the first argument, immediately followed by two tuple arguments used for piecewise construction of the elements of the pair object.