Annex D (normative) Compatibility features [depr]

D.8 Old adaptable function bindings [depr.func.adaptor.binding]

D.8.1 Weak result types [depr.weak.result_type]

Аcall wrapper может иметьweak result type. Если это так, тип его типа членаresult_­type основан на типеT целевого объекта оболочки:

  • еслиT - указатель на тип функции, result_­type должен быть синонимом возвращаемого типаT;

  • еслиT - указатель на функцию-член, result_­type должен быть синонимом возвращаемого типаT;

  • еслиT это тип класса, а qualified-idT​::​result_­type действительный и обозначает тип ([temp.deduct]), тоresult_­type должен быть синонимом дляT​::​result_­type;

  • иначеresult_­type не определяется.

D.8.2 Typedefs to support function binders [depr.func.adaptor.typedefs]

Чтобы включить старые функции адаптеров для управления объектами функции , которые принимают один или два аргумент, многие из функциональных объектов в настоящем стандарте , соответственно , обеспечивают typedef-names argument_­type иresult_­type для функциональных объектов , которые принимают один аргумент и first_­argument_­type,second_­argument_­typeиresult_­type для функциональных объектов , которые принимают два аргумента.

Следующие имена членов определены в дополнение к именам, указанным в Пункте[function.objects]:

namespace std {
  template<class T> struct owner_less<shared_ptr<T>> {
    using result_type          = bool;
    using first_argument_type  = shared_ptr<T>;
    using second_argument_type = shared_ptr<T>;
  };

  template<class T> struct owner_less<weak_ptr<T>> {
    using result_type          = bool;
    using first_argument_type  = weak_ptr<T>;
    using second_argument_type = weak_ptr<T>;
  };

  template <class T> class reference_wrapper {
  public :
    using result_type          = see below; // not always defined
    using argument_type        = see below; // not always defined
    using first_argument_type  = see below; // not always defined
    using second_argument_type = see below; // not always defined
  };

  template <class T> struct plus {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = T;
  };

  template <class T> struct minus {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = T;
  };

  template <class T> struct multiplies {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = T;
  };

  template <class T> struct divides {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = T;
  };

  template <class T> struct modulus {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = T;
  };

  template <class T> struct negate {
    using argument_type = T;
    using result_type   = T;
  };

  template <class T> struct equal_to {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = bool;
  };

  template <class T> struct not_equal_to {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = bool;
  };

  template <class T> struct greater {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = bool;
  };

  template <class T> struct less {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = bool;
  };

  template <class T> struct greater_equal {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = bool;
  };

  template <class T> struct less_equal {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = bool;
  };

  template <class T> struct logical_and {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = bool;
  };

  template <class T> struct logical_or {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = bool;
  };

  template <class T> struct logical_not {
    using argument_type = T;
    using result_type   = bool;
  };

  template <class T> struct bit_and {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = T;
  };

  template <class T> struct bit_or {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = T;
  };

  template <class T> struct bit_xor {
    using first_argument_type  = T;
    using second_argument_type = T;
    using result_type          = T;
  };

  template <class T> struct bit_not {
    using argument_type = T;
    using result_type   = T;
  };

  template<class R, class T1>
  class function<R(T1)> {
  public:
    using argument_type = T1;
  };

  template<class R, class T1, class T2>
  class function<R(T1, T2)> {
  public:
    using first_argument_type  = T1;
    using second_argument_type = T2;
  };
}

reference_­wrapper<T> имеетweak result type. ЕслиT - это тип функции, result_­type должен быть синонимом возвращаемого типаT.

Специализация шаблонаreference_­wrapper<T> должна определять вложенный тип, названныйargument_­type как синоним,T1 только если типT является одним из следующих:

  • тип функции или указатель на тип функции, принимающий один аргумент типаT1

  • указатель на функцию-членR T0​::​f()cv (гдеcv представляет cv-квалификаторы функции-члена); типT1 этоcvT0*

  • тип класса, где qualified-idT​::​argument_­type допустим и обозначает тип ([temp.deduct]); типT1 естьT​::​argument_­type.

Создание экземпляра шаблонаreference_­wrapper<T> должно определять два вложенных типа с именамиfirst_­argument_­type иsecond_­argument_­type как синонимы дляT1 иT2, соответственно, только если типT является одним из следующих:

  • тип функции или указатель на тип функции, принимающий два аргумента типаT1 иT2

  • указатель на функцию-членR T0​::​f(T2)cv (гдеcv представляет cv-квалификаторы функции-члена); типT1 этоcvT0*

  • тип класса , где qualified-ids T​::​first_­argument_­type иT​::​second_­argument_­type являются действительными и оба типа обозначают ([temp.deduct]); типT1 естьT​::​first_­argument_­type и типT2 естьT​::​second_­argument_­type.

Все включенные специализацииhash<Key> изhash ([unord.hash]) обеспечивают два вложенных типов,result_­type иargument_­type, которые должны быть синонимыsize_­t иKey, соответственно.

Обертка переадресации вызовов,g возвращаемая вызовомbind(f, bound_­args...) ([func.bind.bind]), должна иметьweak result type.

Обертка переадресации вызова,g возвращаемая вызовомbind<R>(f, bound_­args...) ([func.bind.bind]), должна иметь вложенный тип,result_­type определенный как синоним дляR.

Простая оболочка вызова, возвращаемая из вызова,mem_­fn(pm) должна иметь вложенный тип,result_­type который является синонимом возвращаемого типа,pm когдаpm является указателем на функцию-член.

Простая оболочка вызова, возвращаемая при вызове,mem_­fn(pm) должна определять два вложенных типа с именамиargument_­type иresult_­type как синонимы дляcvT* иRet, соответственно, когдаpm является указателем на функцию-член с квалификатором cvcv и не принимает аргументов, гдеRet -pmтип возвращаемого значения.

Простая оболочка вызова, возвращаемая из вызова,mem_­fn(pm) должна определять три вложенных типа с именамиfirst_­argument_­type,second_­argument_­typeиresult_­type как синонимы дляcvT*,T1иRet, соответственно, когдаpm является указателем на функцию-член с квалификатором cvcv и принимает один аргумент типаT1, гдеRet -pmэто return тип.

Следующие имена членов определены в дополнение к именам, указанным в Пункте[containers]:

namespace std {
  template <class Key, class T, class Compare, class Allocator>
  class map<Key, T, Compare, Allocator>::value_compare {
  public:
    using result_type          = bool;
    using first_argument_type  = value_type;
    using second_argument_type = value_type;
  };

  template <class Key, class T, class Compare, class Allocator>
  class multimap<Key, T, Compare, Allocator>::value_compare {
  public:
    using result_type          = bool;
    using first_argument_type  = value_type;
    using second_argument_type = value_type;
  };
}

D.8.3 Negators [depr.negators]

В шапку внесены следующие дополнения:<functional>

namespace std {
  template <class Predicate> class unary_negate;
  template <class Predicate>
    constexpr unary_negate<Predicate> not1(const Predicate&);
  template <class Predicate> class binary_negate;
  template <class Predicate>
    constexpr binary_negate<Predicate> not2(const Predicate&);
}

Отрицателиnot1 иnot2 принимают унарный и бинарный предикаты соответственно и возвращают их логические отрицания ([expr.unary.op]).

template <class Predicate>
class unary_negate {
public:
  constexpr explicit unary_negate(const Predicate& pred);
  constexpr bool operator()(const typename Predicate::argument_type& x) const;
  using argument_type = typename Predicate::argument_type;
  using result_type   = bool;
};

constexpr bool operator()(const typename Predicate::argument_type& x) const;

Returns:!pred(x).

template <class Predicate> constexpr unary_negate<Predicate> not1(const Predicate& pred);

Returns:unary_­negate<Predicate>(pred).

template <class Predicate>
class binary_negate {
public:
  constexpr explicit binary_negate(const Predicate& pred);
  constexpr bool operator()(const typename Predicate::first_argument_type& x,
                            const typename Predicate::second_argument_type& y) const;
  using first_argument_type  = typename Predicate::first_argument_type;
  using second_argument_type = typename Predicate::second_argument_type;
  using result_type          = bool;

};

constexpr bool operator()(const typename Predicate::first_argument_type& x, const typename Predicate::second_argument_type& y) const;

Returns:!pred(x,y).

template <class Predicate> constexpr binary_negate<Predicate> not2(const Predicate& pred);

Returns:binary_­negate<Predicate>(pred).