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]

A call wrapper ([func.def]) may have a weak result type.
If it does, the type of its member type result_­type is based on the type T of the wrapper's target object:
  • if T is a pointer to function type, result_­type shall be a synonym for the return type of T;
  • if T is a pointer to member function, result_­type shall be a synonym for the return type of T;
  • if T is a class type and the qualified-id T​::​result_­type is valid and denotes a type ([temp.deduct]), then result_­type shall be a synonym for T​::​result_­type;
  • otherwise result_­type shall not be defined.

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

To enable old function adaptors to manipulate function objects that take one or two arguments, many of the function objects in this International Standard correspondingly provide typedef-names argument_­type and result_­type for function objects that take one argument and first_­argument_­type, second_­argument_­type, and result_­type for function objects that take two arguments.
The following member names are defined in addition to names specified in Clause [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> has a weak result type ([depr.weak.result_type]).
If T is a function type, result_­type shall be a synonym for the return type of T.
The template specialization reference_­wrapper<T> shall define a nested type named argument_­type as a synonym for T1 only if the type T is any of the following:
  • a function type or a pointer to function type taking one argument of type T1
  • a pointer to member function R T0​::​f() cv (where cv represents the member function's cv-qualifiers); the type T1 is cv T0*
  • a class type where the qualified-id T​::​argument_­type is valid and denotes a type ([temp.deduct]); the type T1 is T​::​argument_­type.
The template instantiation reference_­wrapper<T> shall define two nested types named first_­argument_­type and second_­argument_­type as synonyms for T1 and T2, respectively, only if the type T is any of the following:
  • a function type or a pointer to function type taking two arguments of types T1 and T2
  • a pointer to member function R T0​::​f(T2) cv (where cv represents the member function's cv-qualifiers); the type T1 is cv T0*
  • a class type where the qualified-ids T​::​first_­argument_­type and T​::​second_­argument_­type are both valid and both denote types ([temp.deduct]); the type T1 is T​::​first_­argument_­type and the type T2 is T​::​second_­argument_­type.
All enabled specializations hash<Key> of hash ([unord.hash]) provide two nested types, result_­type and argument_­type, which shall be synonyms for size_­t and Key, respectively.
The forwarding call wrapper g returned by a call to bind(f, bound_­args...) ([func.bind.bind]) shall have a weak result type ([depr.weak.result_type]).
The forwarding call wrapper g returned by a call to bind<R>(f, bound_­args...) ([func.bind.bind]) shall have a nested type result_­type defined as a synonym for R.
The simple call wrapper returned from a call to mem_­fn(pm) shall have a nested type result_­type that is a synonym for the return type of pm when pm is a pointer to member function.
The simple call wrapper returned from a call to mem_­fn(pm) shall define two nested types named argument_­type and result_­type as synonyms for cv T* and Ret, respectively, when pm is a pointer to member function with cv-qualifier cv and taking no arguments, where Ret is pm's return type.
The simple call wrapper returned from a call to mem_­fn(pm) shall define three nested types named first_­argument_­type, second_­argument_­type, and result_­type as synonyms for cv T*, T1, and Ret, respectively, when pm is a pointer to member function with cv-qualifier cv and taking one argument of type T1, where Ret is pm's return type.
The following member names are defined in addition to names specified in Clause [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]

The header <functional> has the following additions:
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&);
}
Negators not1 and not2 take a unary and a binary predicate, respectively, and return their logical negations ([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).