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, class U2>
constexpr explicit(see below) pair(U1&& x, U2&& y);
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... Args1, class... Args2>
constexpr pair(piecewise_construct_t,
tuple<Args1...> first_args, tuple<Args2...> second_args);
constexpr pair& operator=(const pair& p);
template<class U1, class U2>
constexpr pair& operator=(const pair<U1, U2>& p);
constexpr pair& operator=(pair&& p) noexcept(see below);
template<class U1, class U2>
constexpr pair& operator=(pair<U1, U2>&& p);
constexpr void swap(pair& p) noexcept(see below);
};
template<class T1, class T2>
pair(T1, T2) -> pair<T1, T2>;
}
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
.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 satisfy the
requirements for a constexpr function
.If
(is_trivially_destructible_v<T1> && is_trivially_destructible_v<T2>)
is
true, then the destructor of
pair is trivial
.pair<T, U> is a structural type (
[temp.param])
if
T and
U are both structural types
. Two values
p1 and
p2 of type
pair<T, U>
are template-argument-equivalent (
[temp.type]) if and only if
p1.first and
p2.first are template-argument-equivalent and
p1.second and
p2.second are template-argument-equivalent
.constexpr explicit(see below) pair();
Constraints:
- is_default_constructible_v<first_type> is true and
- is_default_constructible_v<second_type> is true.
Effects: Value-initializes
first and
second. Remarks: The expression inside
explicit evaluates to
true
if and only if either
first_type or
second_type is not implicitly default-constructible
. [
Note 1:
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]
constexpr explicit(see below) pair(const T1& x, const T2& y);
Constraints:
- is_copy_constructible_v<first_type> is true and
- is_copy_constructible_v<second_type> is true.
Effects: Initializes
first with
x and
second with
y. Remarks: The expression inside explicit is equivalent to:
!is_convertible_v<const first_type&, first_type> ||
!is_convertible_v<const second_type&, second_type>
template<class U1, class U2> constexpr explicit(see below) pair(U1&& x, U2&& y);
Constraints:
- is_constructible_v<first_type, U1> is true and
- is_constructible_v<second_type, U2> is true.
Effects: Initializes
first with
std::forward<U1>(x) and
second
with
std::forward<U2>(y). Remarks: The expression inside explicit is equivalent to:
!is_convertible_v<U1, first_type> || !is_convertible_v<U2, second_type>
template<class U1, class U2> constexpr explicit(see below) pair(const pair<U1, U2>& p);
Constraints:
- is_constructible_v<first_type, const U1&> is true and
- is_constructible_v<second_type, const U2&> is true.
Effects: Initializes members from the corresponding members of the argument
. Remarks: The expression inside explicit is equivalent to:
!is_convertible_v<const U1&, first_type> || !is_convertible_v<const U2&, second_type>
template<class U1, class U2> constexpr explicit(see below) pair(pair<U1, U2>&& p);
Constraints:
- is_constructible_v<first_type, U1> is true and
- is_constructible_v<second_type, U2> is true.
Effects: Initializes
first with
std::forward<U1>(p.first)
and
second with
std::forward<U2>(p.second). Remarks: The expression inside explicit is equivalent to:
!is_convertible_v<U1, first_type> || !is_convertible_v<U2, second_type>
template<class... Args1, class... Args2>
constexpr pair(piecewise_construct_t,
tuple<Args1...> first_args, tuple<Args2...> second_args);
Mandates:
- 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.constexpr pair& operator=(const pair& p);
Effects: Assigns
p.first to
first and
p.second to
second. Remarks: This operator is 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> constexpr pair& operator=(const pair<U1, U2>& p);
Constraints:
- is_assignable_v<first_type&, const U1&> is true and
- is_assignable_v<second_type&, const U2&> is true.
Effects: Assigns
p.first to
first and
p.second to
second. constexpr pair& operator=(pair&& p) noexcept(see below);
Constraints:
- is_move_assignable_v<first_type> is true and
- is_move_assignable_v<second_type> is true.
Effects: Assigns to first with std::forward<first_type>(p.first)
and to second with
std::forward<second_type>(p.second). 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> constexpr pair& operator=(pair<U1, U2>&& p);
Constraints:
- is_assignable_v<first_type&, U1> is true and
- is_assignable_v<second_type&, U2> is true.
Effects: Assigns to first with std::forward<U1>(p.first)
and to second with
std::forward<U2>(p.second). constexpr void swap(pair& p) noexcept(see below);
Effects: Swaps
first with
p.first and
second with
p.second. Remarks: The expression inside noexcept is equivalent to:
is_nothrow_swappable_v<first_type> && is_nothrow_swappable_v<second_type>