23 General utilities library [utilities]
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();
Effects:
Value-initializes
first and
second. 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);
Effects:
Initializes
first with
x and
second with
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);
Effects:
Initializes
first with
std::forward<U1>(x) and
second
with
std::forward<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);
Effects:
Initializes members from the corresponding members of the argument
. 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);
Effects: Assigns
p.first to
first and
p.second to
second. 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);
Effects: Assigns
p.first to
first and
p.second to
second. 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);
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>
template <class T1, class T2>
constexpr bool operator==(const pair<T1, T2>& x, const pair<T1, T2>& y);
Returns:
x.first == y.first && x.second == y.second. template <class T1, class T2>
constexpr bool operator<(const pair<T1, T2>& x, const pair<T1, T2>& y);
Returns:
x.first < y.first || (!(y.first < x.first) && x.second < y.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> void swap(pair<T1, T2>& x, pair<T1, T2>& y)
noexcept(noexcept(x.swap(y)));
Effects: As if by
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.[
Example: In place of:
return pair<int, double>(5, 3.1415926);
a C++ program may contain:
return make_pair(5, 3.1415926);
—
end example ]
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;
Requires: T1 and
T2 are distinct types
. Otherwise, the program is ill-formed
.Returns: A reference to
p.first. 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;
Requires: T1 and
T2 are distinct types
. Otherwise, the program is ill-formed
.Returns: A reference to
p.second. 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 (
[tuple]) arguments used
for piecewise construction of the elements of the
pair object
.