23 General utilities library [utilities]

23.4 Pairs [pairs]

23.4.1 In general [pairs.general]

Библиотека предоставляет шаблон для разнородных пар значений. Библиотека также предоставляет соответствующий шаблон функций для упрощения их построения и несколько шаблонов, которые обеспечивают доступ кpair объектам, как если бы они былиtuple объектами (см.[tuple.helper] И[tuple.elem]).

23.4.2 Class template pair [pairs.pair]

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>;
}

Конструкторы и функции-членыpair не должны вызывать исключения, если одна из поэлементных операций, указанных для вызова для этой операции, не вызывает исключение.

Конструктор перемещения и копирования по умолчанию, соответственно,pair должен быть функцией constexpr тогда и только тогда, когда все требуемые поэлементные инициализации для копирования и перемещения, соответственно, будут удовлетворять требованиям для функции constexpr. Деструкторpair должен быть тривиальным деструктором, если (is_­trivially_­destructible_­v<T1> && is_­trivially_­destructible_­v<T2>) естьtrue.

EXPLICIT constexpr pair();

Effects: Значение инициализируетfirst иsecond.

Remarks: Этот конструктор не должен участвовать в разрешении перегрузки , если is_­default_­constructible_­v<first_­type> неtrue и is_­default_­constructible_­v<second_­type> являетсяtrue. [ Note: Это поведение может быть реализовано с помощью шаблона конструктора с аргументами шаблона по умолчанию. ] Конструктор является явным тогда и только тогда, когда любой из них или не является неявно конструктивным по умолчанию. [ Это поведение может быть реализовано с помощью трейта, который проверяет, можно ли инициализировать a или a . ] end notefirst_­type second_­type Note: const first_­type& const second_­type&{}end note

EXPLICIT constexpr pair(const T1& x, const T2& y);

Effects: Инициализируетсяfirst с помощьюx иsecond с помощьюy.

Remarks: Этот конструктор не должен участвовать в разрешении перегрузки , еслиis_­copy_­constructible_­v<first_­type> неtrue и is_­copy_­constructible_­v<second_­type> являетсяtrue. Конструктор является явным тогда и только тогда, когда is_­convertible_­v<const first_­type&, first_­type> естьfalse или is_­convertible_­v<const second_­type&, second_­type> естьfalse.

template<class U1, class U2> EXPLICIT constexpr pair(U1&& x, U2&& y);

Effects: Инициализируетсяfirst с помощью std​::​forward<U1>(x) иsecond с помощьюstd​::​forward<U2>(y).

Remarks: Этот конструктор не должен участвовать в разрешении перегрузки , если is_­constructible_­v<first_­type, U1&&> неtrue и is_­constructible_­v<second_­type, U2&&> являетсяtrue. Конструктор является явным тогда и только тогда, когда is_­convertible_­v<U1&&, first_­type> естьfalse или is_­convertible_­v<U2&&, second_­type> естьfalse.

template<class U1, class U2> EXPLICIT constexpr pair(const pair<U1, U2>& p);

Effects: Инициализирует члены из соответствующих членов аргумента.

Remarks: Этот конструктор не должен участвовать в разрешении перегрузки , если is_­constructible_­v<first_­type, const U1&> неtrue и is_­constructible_­v<second_­type, const U2&> являетсяtrue. Конструктор является явным тогда и только тогда, когда is_­convertible_­v<const U1&, first_­type> естьfalse или is_­convertible_­v<const U2&, second_­type> естьfalse.

template<class U1, class U2> EXPLICIT constexpr pair(pair<U1, U2>&& p);

Effects: Инициализируетсяfirst с помощью std​::​forward<U1>(p.first) иsecond с помощью std​::​forward<U2>(​p.second).

Remarks: Этот конструктор не должен участвовать в разрешении перегрузки , если is_­constructible_­v<first_­type, U1&&> неtrue и is_­constructible_­v<second_­type, U2&&> являетсяtrue. Конструктор является явным тогда и только тогда, когда is_­convertible_­v<U1&&, first_­type> естьfalse или is_­convertible_­v<U2&&, second_­type> есть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&&...> естьtrue иis_­constructible_­v<second_­type, Args2&&...> естьtrue.

Effects: Инициализируетсяfirst аргументами типов, Args1... полученных путем пересылки элементов,first_­args и инициализируетсяsecond аргументами типов,Args2... полученных пересылкой элементовsecond_­args. (Здесь пересылка элементаx типаU внутриtuple объекта означает вызов std​::​forward<U>(x).) Вызывается эта форма конструкции, при которой аргументы конструктора дляfirst иsecond предоставляются в отдельном tuple объектеpiecewise construction.

pair& operator=(const pair& p);

Effects: Присваиваетp.first кfirst иp.second кsecond.

Remarks: Этот оператор должен быть определен как удален , если is_­copy_­assignable_­v<first_­type> неtrue иis_­copy_­assignable_­v<second_­type> являетсяtrue.

Returns:*this.

template<class U1, class U2> pair& operator=(const pair<U1, U2>& p);

Effects: Присваиваетp.first кfirst иp.second кsecond.

Remarks: Этот оператор не должен участвовать в разрешении перегрузки , если is_­assignable_­v<first_­type&, const U1&> неtrue иis_­assignable_­v<second_­type&, const U2&> являетсяtrue.

Returns:*this.

pair& operator=(pair&& p) noexcept(see below);

Effects: Назначает кfirst сstd​::​forward<first_­type>(p.first) и кsecond с
std​::​forward<second_­type>(p.second).

Remarks: Этот оператор должен быть определен как удален , если is_­move_­assignable_­v<first_­type> неtrue иis_­move_­assignable_­v<second_­type> являетсяtrue.

Remarks: Выражение внутриnoexcept эквивалентно:

is_nothrow_move_assignable_v<T1> && is_nothrow_move_assignable_v<T2>

Returns:*this.

template<class U1, class U2> pair& operator=(pair<U1, U2>&& p);

Effects: Назначает кfirst сstd​::​forward<U>(p.first) и кsecond с
std​::​forward<V>(p.second).

Remarks: Этот оператор не должен участвовать в разрешении перегрузки , если is_­assignable_­v<first_­type&, U1&&> неtrue иis_­assignable_­v<second_­type&, U2&&> являетсяtrue.

Returns:*this.

void swap(pair& p) noexcept(see below);

Requires: first должны бытьswappable with p.first иsecond должны быть замененыp.second.

Effects: Меняет местами first сp.first и second сp.second.

Remarks: Выражение внутриnoexcept эквивалентно:

is_nothrow_swappable_v<first_type> && is_nothrow_swappable_v<second_type>

23.4.3 Specialized algorithms [pairs.spec]

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);

Returns:!(x == y).

template <class T1, class T2> constexpr bool operator>(const pair<T1, T2>& x, const pair<T1, T2>& y);

Returns:y < x.

template <class T1, class T2> constexpr bool operator>=(const pair<T1, T2>& x, const pair<T1, T2>& y);

Returns:!(x < y).

template <class T1, class T2> constexpr bool operator<=(const pair<T1, T2>& x, const pair<T1, T2>& y);

Returns:!(y < x).

template<class T1, class T2> void swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y)));

Effects: Как будто мимоx.swap(y).

Remarks: Эта функция не будет участвовать в разрешении перегрузки , если is_­swappable_­v<T1> неtrue и is_­swappable_­v<T2> является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)), гдеV1 иV2 определяются следующим образом: ПустьUi будет decay_­t<Ti> для каждогоTi. ЕслиUi является специализациейreference_­wrapper, тоVi естьUi​::​type&, иначеVi -Ui.

[ Example: Вместо:

  return pair<int, double>(5, 3.1415926);   // explicit types

программа на C ++ может содержать:

  return make_pair(5, 3.1415926);           // types are deduced

end example]

23.4.4 Tuple-like access to pair [pair.astuple]

template <class T1, class T2> struct tuple_size<pair<T1, T2>> : integral_constant<size_t, 2> { };

tuple_element<0, pair<T1, T2>>::type

Value: ТипT1.

tuple_element<1, pair<T1, T2>>::type

Value: Тип Т2.

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: ЕслиI == 0 возвращает ссылку наp.first; еслиI == 1 возвращает ссылку наp.second; в противном случае программа будет некорректной.

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 иT2 являются разными типами. В противном случае программа имеет неверный формат.

Returns: Ссылка на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 иT2 являются разными типами. В противном случае программа имеет неверный формат.

Returns: Ссылка наp.second.

23.4.5 Piecewise construction [pair.piecewise]

struct piecewise_construct_t { explicit piecewise_construct_t() = default; }; inline constexpr piecewise_construct_t piecewise_construct{};

Этоstructpiecewise_­construct_­t пустой структурный тип, используемый как уникальный тип для устранения неоднозначности перегрузки конструктора и функции. В частности, pair имеет конструктор сpiecewise_­construct_­t первым аргументом, за которым сразу следуют дваtuple аргумента, используемых для кусочного построения элементовpair объекта.