<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

<title>Deprecating unary/binary_function</title>

<style type="text/css">
  p {text-align:justify}
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  blockquote.note
  {
   background-color:#E0E0E0;
   padding-left: 15px;
   padding-right: 15px;
   padding-top: 1px;
   padding-bottom: 1px;
  }
</style>
</head><body>
<address style="text-align: left;">
Document number: N3145=10-0135<br>
Date: 2010-10-06<br>
Author: Daniel Kr&uuml;gler<br>
Project: Programming Language C++, Library Working Group<br>
Reply-to: <a href="mailto:daniel.kruegler@googlemail.com">Daniel Kr&uuml;gler</a>
</address>
<hr>
<h1 style="text-align: center;">Deprecating <tt>unary_function</tt> and <tt>binary_function</tt></h1>
<p>
<strong>Addressed NB comments</strong>: 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3118.html#GB95">GB 95</a>
<p>
<strong>Addressed issues</strong>: 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#1290">LWG 1290</a>,
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#1279">LWG 1279</a>
<p>
<h2><a name="Introduction"></a>Introduction</h2>
<p>
The templates
<p>
<blockquote><pre>
template &lt;class Arg, class Result&gt;
struct unary_function {
  typedef Arg argument_type;
  typedef Result result_type;
};

template &lt;class Arg1, class Arg2, class Result&gt;
struct binary_function {
  typedef Arg1 first_argument_type;
  typedef Arg2 second_argument_type;
  typedef Result result_type;
};
</pre></blockquote>
<p>
are types that were provided to solely simplify the definition of some canonical typenames in
functor types. Unfortunately these library components were underspecified, and the current wording 
would basically allow to specialize them for any user-defined type, but the library does not 
clarify the restrictions of such specializations. Further-on during TR1 a protocol was introduced 
that based on inheritance-relations of function object types and several other components, like 
<tt>reference_wrapper</tt>, <tt>bind</tt>, <tt>function</tt>, and others.
<p>
<h2><a name="Discussion"></a>Discussion</h2>
<p>
Our experience with concepts gives us confidence that it is rarely necessary to depend on specific 
base class-derived class relations, if availability of types and functions is sufficient. The new 
language tools allow us even in the absence of language-supported concepts to deduce the existence 
of typenames in class types, which would introduce a much weaker coupling among them. Another advantage
of replacing inheritance by associated types is the fact, that this will reduce the number of cases,
where ambiguities arise: This can easily happen, if a type would inherit both from <tt>unary_function</tt>
and <tt>binary_function</tt> (This makes sense, if a functor is both an unary and a binary function
object).
<p>	
During the Rapperswil meeting consensus was found for deprecating the types <tt>unary_function</tt> and 
<tt>binary_function</tt> and the protocol that was using them. This proposal describes the details of
such an approach.
<p>
<h2><a name="Proposed_resolution"></a>Proposed resolution</h2>
<p>
The proposed wording changes refer to <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3126.pdf">N3126</a>.
<p>
<ol>
<li>Change [function.objects]/2, header <tt>&lt;functional&gt;</tt> synopsis as indicated. The intent is to
	deprecate the adaptable function protocol and the adapter classes that are now much better represented by
	<tt>bind</tt> and lambda closures:
<p>
<blockquote><pre>
namespace std {
  // <em><del>20.8.3</del><ins>[depr.lib.base]</ins>, base <ins>(deprecated)</ins></em>:
  template &lt;class Arg, class Result&gt; struct unary_function;
  template &lt;class Arg1, class Arg2, class Result&gt; struct binary_function;

  [..]

  // <em><del>20.8.9</del><ins>[depr.lib.negators]</ins>, negators <ins>(deprecated)</ins></em>:
  template &lt;class Predicate&gt; class unary_negate;
  template &lt;class Predicate&gt;
    unary_negate&lt;Predicate&gt; not1(const Predicate&amp;);
  template &lt;class Predicate&gt; class binary_negate;
  template &lt;class Predicate&gt;
    binary_negate&lt;Predicate&gt; not2(const Predicate&amp;);

  [..]
  
  // <em><del>20.8.11</del><ins>[depr.lib.funptr.adaptors]</ins>, adaptors <ins>(deprecated)</ins></em>:
  template &lt;class Arg, class Result&gt; class pointer_to_unary_function;
  template &lt;class Arg, class Result&gt;
    pointer_to_unary_function&lt;Arg,Result&gt; ptr_fun(Result (*)(Arg));
  template &lt;class Arg1, class Arg2, class Result&gt;
    class pointer_to_binary_function;
  template &lt;class Arg1, class Arg2, class Result&gt;
    pointer_to_binary_function&lt;Arg1,Arg2,Result&gt;
      ptr_fun(Result (*)(Arg1,Arg2));

  // <em><del>20.8.12</del><ins>[depr.lib.memptr.adaptors]</ins>, adaptors <ins>(deprecated)</ins></em>: 
  template&lt;class S, class T&gt; class mem_fun_t; 
  template&lt;class S, class T, class A&gt; class mem_fun1_t; 
  template&lt;class S, class T&gt;
  	mem_fun_t&lt;S,T&gt; mem_fun(S (T::*f)()); 
  template&lt;class S, class T, class A&gt;
    mem_fun1_t&lt;S,T,A&gt; mem_fun(S (T::*f)(A)); 
  template&lt;class S, class T&gt; class mem_fun_ref_t; 
  template&lt;class S, class T, class A&gt; class mem_fun1_ref_t; 
  template&lt;class S, class T&gt; 
    mem_fun_ref_t&lt;S,T&gt; mem_fun_ref(S (T::*f)()); 
  template&lt;class S, class T, class A&gt;
  	mem_fun1_ref_t&lt;S,T,A&gt; mem_fun_ref(S (T::*f)(A));
  
  template &lt;class S, class T&gt; class const_mem_fun_t; 
  template &lt;class S, class T, class A&gt; class const_mem_fun1_t; 
  template &lt;class S, class T&gt; 
  	const_mem_fun_t&lt;S,T&gt; mem_fun(S (T::*f)() const); 
  template &lt;class S, class T, class A&gt;
  	const_mem_fun1_t&lt;S,T,A&gt; mem_fun(S (T::*f)(A) const); 
  template &lt;class S, class T&gt; class const_mem_fun_ref_t; 
  template &lt;class S, class T, class A&gt; class const_mem_fun1_ref_t; 
  template &lt;class S, class T&gt; 
    const_mem_fun_ref_t&lt;S,T&gt; mem_fun_ref(S (T::*f)() const); 
  template &lt;class S, class T, class A&gt; 
  	const_mem_fun1_ref_t&lt;S,T,A&gt; mem_fun_ref(S (T::*f)(A) const);
	
  [..]
}	
</pre></blockquote>
<p>
</li>
<li>Remove sub-clause [base] and insert a new sub-clause just before the current D.9 [depr.lib.binders] as follows:
<p>
<del>20.8.3 Base [base]</del>
<p>
<del>1 The following classes are provided to simplify the typedefs of the argument and result types:</del>
<p>
<blockquote><pre>
<del>namespace std {
  template &lt;class Arg, class Result&gt;
  struct unary_function {
    typedef Arg argument_type;
    typedef Result result_type;
  };
}
namespace std {
  template &lt;class Arg1, class Arg2, class Result&gt;
  struct binary_function {
    typedef Arg1 first_argument_type;
    typedef Arg2 second_argument_type;
    typedef Result result_type;
  };
}</del>
</pre></blockquote>
<p>
<ins>D.?? Base [depr.lib.base]</ins>
<p>
<blockquote><pre>
<ins>namespace std {
  template &lt;class Arg, class Result&gt;
  struct unary_function {
    typedef Arg argument_type;
    typedef Result result_type;
  };
}
namespace std {
  template &lt;class Arg1, class Arg2, class Result&gt;
  struct binary_function {
    typedef Arg1 first_argument_type;
    typedef Arg2 second_argument_type;
    typedef Result result_type;
  };
}</ins>
</pre></blockquote>
<p>
</li>
<li>Change [refwrap] as indicated. The intent is to replace the inheritance requirement by corresponding typedef requirements:
<p>
<blockquote><pre>
namespace std {
  template &lt;class T&gt; class reference_wrapper
    <del>: public unary_function&lt;T1, R&gt; // <em>see below</em></del>
    <del>: public binary_function&lt;T1, T2, R&gt; // <em>see below</em></del>
  {
  public :
    // types
    typedef T type;
    typedef <em>see below</em> result_type; // not always defined
    <ins>typedef <em>see below</em> argument_type; // not always defined</ins>
    <ins>typedef <em>see below</em> first_argument_type; // not always defined</ins>
    <ins>typedef <em>see below</em> second_argument_type; // not always defined</ins>

    // construct/copy/destroy
    [..]  
  };
}
</pre></blockquote>
<p>
</li>
<li>Change [refwrap]/3+4 as indicated. The intent is to replace the currently required inheritance-rules by associated type-rules:
<p>
3 The template instantiation <tt>reference_wrapper&lt;T&gt;</tt> shall <del>be derived from <tt>std::unary_function&lt;T1, R&gt;</tt></del><ins>define 
	a nested type named <tt>argument_type</tt> as a synonym for <tt>T1</tt></ins> only if the type <tt>T</tt> is any of the following:
<ul>
<li>a function type or a pointer to function type taking one argument of type <tt>T1</tt><del> and returning <tt>R</tt></del></li>
<li>a pointer to member function <tt>R T0::f</tt> <em>cv</em> (where <em>cv</em> represents the member function's cv-qualifiers);
the type <tt>T1</tt> is <em>cv</em> <tt>T0*</tt></li>
<li>a class type <del>that is derived from <tt>std::unary_function&lt;T1, R&gt;</tt></del><ins>with a member type <tt>argument_type</tt>; 
	the type <tt>T1</tt> is <tt>T::argument_type</tt></ins></li>
</ul>
<p>
4 The template instantiation <tt>reference_wrapper&lt;T&gt;</tt> shall <del>be derived from <tt>std::binary_function&lt;T1, T2, R&gt;</tt></del><ins>define 
	two nested types named <tt>first_argument_type</tt> and <tt>second_argument_type</tt> as a synonym for <tt>T1</tt> and <tt>T2</tt>, 
	respectively,</ins> only if the type <tt>T</tt> is any of the following:
<ul>
<li>a function type or a pointer to function type taking two arguments of types <tt>T1</tt> and <tt>T2</tt><del> and returning <tt>R</tt></del></li>
<li>a pointer to member function <tt>R T0::f(T2)</tt> <em>cv</em> (where <em>cv</em> represents the member function's cv-qualifiers);
the type <tt>T1</tt> is <em>cv</em> <tt>T0*</tt></li>
<li>a class type <del>that is derived from <tt>std::binary_function&lt;T1, T2, R&gt;</tt></del><ins>with member types 
	<tt>first_argument_type</tt> and <tt>second_argument_type</tt>; the type <tt>T1</tt> is <tt>T::first_argument_type</tt> 
	and the type <tt>T2</tt> is <tt>T::second_argument_type</tt></ins></li>
</ul>
<p>
</li>
<li>Change the template definitions in sub-clause [arithmetic.operations] as indicated. The intent is to replace the derivation from 
	<tt>binary_function</tt> and <tt>unary_function</tt> by correspondingly existing typedefs:
<p>
<blockquote><pre>
template &lt;class T&gt; struct plus <del>: binary_function&lt;T,T,T&gt;</del> {
  <ins>typedef T first_argument_type;</ins>
  <ins>typedef T second_argument_type;</ins>
  <ins>typedef T result_type;</ins>
  T operator()(const T&amp; x, const T&amp; y) const;
};	

[..]

template &lt;class T&gt; struct minus <del>: binary_function&lt;T,T,T&gt;</del> {
  <ins>typedef T first_argument_type;</ins>
  <ins>typedef T second_argument_type;</ins>
  <ins>typedef T result_type;</ins>
  T operator()(const T&amp; x, const T&amp; y) const;
};	

[..]
	
template &lt;class T&gt; struct multiplies <del>: binary_function&lt;T,T,T&gt;</del> {
  <ins>typedef T first_argument_type;</ins>
  <ins>typedef T second_argument_type;</ins>
  <ins>typedef T result_type;</ins>
  T operator()(const T&amp; x, const T&amp; y) const;
};	

[..]

template &lt;class T&gt; struct divides <del>: binary_function&lt;T,T,T&gt;</del> {
  <ins>typedef T first_argument_type;</ins>
  <ins>typedef T second_argument_type;</ins>
  <ins>typedef T result_type;</ins>
  T operator()(const T&amp; x, const T&amp; y) const;
};	

[..]

template &lt;class T&gt; struct modulus <del>: binary_function&lt;T,T,T&gt;</del> {
  <ins>typedef T first_argument_type;</ins>
  <ins>typedef T second_argument_type;</ins>
  <ins>typedef T result_type;</ins>
  T operator()(const T&amp; x, const T&amp; y) const;
};	

[..]

template &lt;class T&gt; struct negate <del>: unary_function&lt;T,T&gt;</del> {
  <ins>typedef T argument_type;</ins>
  <ins>typedef T result_type;</ins>
  T operator()(const T&amp; x) const;
};	
</pre></blockquote>
</li>
<li>Change the template definitions in sub-clause [comparisons] as indicated. The intent is to replace the derivation from 
	<tt>binary_function</tt> by correspondingly existing typedefs:
<p>
<blockquote><pre>
template &lt;class T&gt; struct equal_to <del>: binary_function&lt;T,T,bool&gt;</del> {
  <ins>typedef T first_argument_type;</ins>
  <ins>typedef T second_argument_type;</ins>
  <ins>typedef bool result_type;</ins>
  bool operator()(const T&amp; x, const T&amp; y) const;
};	

[..]

template &lt;class T&gt; struct not_equal_to <del>: binary_function&lt;T,T,bool&gt;</del> {
  <ins>typedef T first_argument_type;</ins>
  <ins>typedef T second_argument_type;</ins>
  <ins>typedef bool result_type;</ins>
  bool operator()(const T&amp; x, const T&amp; y) const;
};	

[..]

template &lt;class T&gt; struct greater <del>: binary_function&lt;T,T,bool&gt;</del> {
  <ins>typedef T first_argument_type;</ins>
  <ins>typedef T second_argument_type;</ins>
  <ins>typedef bool result_type;</ins>
  bool operator()(const T&amp; x, const T&amp; y) const;
};	

[..]

template &lt;class T&gt; struct less <del>: binary_function&lt;T,T,bool&gt;</del> {
  <ins>typedef T first_argument_type;</ins>
  <ins>typedef T second_argument_type;</ins>
  <ins>typedef bool result_type;</ins>
  bool operator()(const T&amp; x, const T&amp; y) const;
};	

[..]

template &lt;class T&gt; struct greater_equal <del>: binary_function&lt;T,T,bool&gt;</del> {
  <ins>typedef T first_argument_type;</ins>
  <ins>typedef T second_argument_type;</ins>
  <ins>typedef bool result_type;</ins>
  bool operator()(const T&amp; x, const T&amp; y) const;
};	

[..]

template &lt;class T&gt; struct less_equal <del>: binary_function&lt;T,T,bool&gt;</del> {
  <ins>typedef T first_argument_type;</ins>
  <ins>typedef T second_argument_type;</ins>
  <ins>typedef bool result_type;</ins>
  bool operator()(const T&amp; x, const T&amp; y) const;
};	
</pre></blockquote>
</li>
<li>Change the template definitions in sub-clause [logical.operations] as indicated. The intent is to replace the derivation from 
	<tt>binary_function</tt> and by <tt>unary_function</tt> correspondingly existing typedefs:
<p>
<blockquote><pre>
template &lt;class T&gt; struct logical_and <del>: binary_function&lt;T,T,bool&gt;</del> {
  <ins>typedef T first_argument_type;</ins>
  <ins>typedef T second_argument_type;</ins>
  <ins>typedef bool result_type;</ins>
  bool operator()(const T&amp; x, const T&amp; y) const;
};	

[..]

template &lt;class T&gt; struct logical_or <del>: binary_function&lt;T,T,bool&gt;</del> {
  <ins>typedef T first_argument_type;</ins>
  <ins>typedef T second_argument_type;</ins>
  <ins>typedef bool result_type;</ins>
  bool operator()(const T&amp; x, const T&amp; y) const;
};	

[..]

template &lt;class T&gt; struct logical_not <del>: unary_function&lt;T,bool&gt;</del> {
  <ins>typedef T argument_type;</ins>
  <ins>typedef bool result_type;</ins>
  bool operator()(const T&amp; x) const;
};	
</pre></blockquote>
</li>
<li>Change the template definitions in sub-clause [bitwise.operations] as indicated. The intent is to replace the derivation from 
	<tt>binary_function</tt> by correspondingly existing typedefs:
<p>
<blockquote><pre>
template &lt;class T&gt; struct bit_and <del>: binary_function&lt;T,T,T&gt;</del> {
  <ins>typedef T first_argument_type;</ins>
  <ins>typedef T second_argument_type;</ins>
  <ins>typedef T result_type;</ins>
  T operator()(const T&amp; x, const T&amp; y) const;
};	

[..]

template &lt;class T&gt; struct bit_or <del>: binary_function&lt;T,T,T&gt;</del> {
  <ins>typedef T first_argument_type;</ins>
  <ins>typedef T second_argument_type;</ins>
  <ins>typedef T result_type;</ins>
  T operator()(const T&amp; x, const T&amp; y) const;
};	

[..]
	
template &lt;class T&gt; struct bit_xor <del>: binary_function&lt;T,T,T&gt;</del> {
  <ins>typedef T first_argument_type;</ins>
  <ins>typedef T second_argument_type;</ins>
  <ins>typedef T result_type;</ins>
  T operator()(const T&amp; x, const T&amp; y) const;
};	
</pre></blockquote>
</li>
<li>Move the complete contents of sub-clause 20.8.9 Negators [negators] as a new sub-clause 
	just after the new sub-clause [depr.lib.base] and before the current D.9 [depr.lib.binders]
	starting with:
<p>
<ins>D.?? Negators [depr.lib.negators]</ins>
<p>
<ins>1 Negators <tt>not1</tt> and <tt>not2</tt> take a unary and a binary predicate, respectively, and return their 
  complements (5.3.1).</ins>
<p>
<blockquote><pre>
  <ins>template &lt;class Predicate&gt;
  class unary_negate
    : public unary_function&lt;typename Predicate::argument_type,bool&gt; {</ins>
</pre></blockquote>
<p>
[..] // <em>Remaining parts from previous 20.8.9 Negators [negators]</em>
</li>
<li>Following the new sub-clause Negators [depr.lib.negators] (see previous bullet). add a new sub-clause [depr.lib.adaptors]
	and insert two further children sub-clauses, [depr.lib.funptr.adaptors] and [depr.lib.memptr.adaptors]. Move the complete contents 
	of sub-clause 20.8.11 Adaptors for pointers to functions [function.pointer.adaptors] as contents of the new sub-clause 
	[depr.lib.funptr.adaptors]. Move the complete contents of sub-clause 20.8.12 Adaptors for pointers to members [member.pointer.adaptors]
	 as contents of the new sub-clause [depr.lib.memptr.adaptors].:
<p>
<ins>D.?? Adaptors [depr.lib.adaptors]</ins>
<p>
<ins>The adaptors <tt>ptr_fun</tt>, <tt>mem_fun</tt>, <tt>mem_fun_ref</tt>, and their corresponding return types are deprecated. 
[ <em>Note</em>: The function template <tt>bind</tt> (20.8.10) provides a better solution. &mdash; <em>end note</em> ]</ins>
<p>	
<ins>D.??.1 Adaptors for pointers to functions [depr.lib.funptr.adaptors]</ins>
<p>
<ins>1 To allow pointers to (unary and binary) functions to work with function adaptors the library provides:</ins>
<p>
<blockquote><pre>
  <ins>template &lt;class Arg, class Result&gt;
  class pointer_to_unary_function : public unary_function&lt;Arg, Result&gt; {</ins>
</pre></blockquote>
<p>
[..] // <em>Remaining parts from previous 20.8.11 Adaptors for pointers to functions [function.pointer.adaptors]</em>
<p>
<ins>D.??.2 Adaptors for pointers to members [depr.lib.memptr.adaptors]</ins>
<p>
<ins>1 The purpose of the following is to provide the same facilities for pointer to members as those provided for
pointers to functions in 20.8.11.:</ins>
<p>
<blockquote><pre>
  <ins>template &lt;class S, class T&gt; class mem_fun_t
    : public unary_function&lt;T*, S&gt; {</ins>
</pre></blockquote>
<p>
[..] // <em>Remaining parts from previous 20.8.12 Adaptors for pointers to members [member.pointer.adaptors]</em>
<p>
</li>
<li>Change [func.memfn]/2+3 as indicated. The intent is to replace the derivation from <tt>binary_function</tt> and 
	<tt>unary_function</tt> by correspondingly existing typedefs:
<p>
2 The simple call wrapper shall <del>be derived from <tt>std::unary_function&lt;<em>cv</em> T*, Ret&gt;</tt></del><ins>define 
	two nested types named <tt>argument_type</tt> and <tt>result_type</tt> as a synonym for <em>cv</em> <tt>T*</tt> and <tt>Ret</tt>, 
	respectively,</ins> when <tt>pm</tt> is a pointer to member function with cv-qualifier <em>cv</em> and taking no arguments, 
	where <tt>Ret</tt> is <tt>pm</tt>'s return type.
<p>
3 The simple call wrapper shall <del>be derived from <tt>std::binary_function&lt;<em>cv</em> T*, T1, Ret&gt;</tt></del><ins>define 
	three nested types named <tt>first_argument_type</tt>, <tt>second_argument_type</tt>, and <tt>result_type</tt> as a synonym for 
	<em>cv</em> <tt>T*</tt>, <tt>T1</tt>, and <tt>Ret</tt>, respectively,</ins> when <tt>pm</tt> is a pointer to member function 
	with cv-qualifier <em>cv</em> and taking one argument of type <tt>T1</tt>, where <tt>Ret</tt> is <tt>pm</tt>'s return type.
</li>
<li>Change 20.8.14.2 [func.wrap.func], class template <tt>function</tt> synopsis as indicated. The intent is to replace the 
	currently required inheritance-rules by associated type-rules:
<p>
<blockquote><pre>
namespace std {
  template&lt;class&gt; class function; // <em>undefined</em>

  template&lt;class R, class... ArgTypes&gt;
  class function&lt;R(ArgTypes...)&gt;
    <del>: public unary_function&lt;T1, R&gt; // <em>iff</em> sizeof...(ArgTypes) == 1 <em>and</em> ArgTypes <em>contains</em> T1</del>
    <del>: public binary_function&lt;T1, T2, R&gt; // <em>iff</em> sizeof...(ArgTypes) == 2 <em>and</em> ArgTypes <em>contains</em> T1 and T2</del>
  {
  public:
    typedef R result_type;
    <ins>typedef T1 argument_type; // <em>iff</em> sizeof...(ArgTypes) == 1 <em>and</em> ArgTypes <em>contains</em> T1</ins>
    <ins>typedef T1 first_argument_type; // <em>iff</em> sizeof...(ArgTypes) == 2 <em>and</em> ArgTypes <em>contains</em> T1 <em>as first type</em></ins>
    <ins>typedef T2 second_argument_type; // <em>iff</em> sizeof...(ArgTypes) == 2 <em>and</em> ArgTypes <em>contains</em> T2 <em>as second type</em></ins>

    // 20.8.14.2.1, construct/copy/destroy:
    [..]
</pre></blockquote>
<p>
</li>
<li>Change 20.9.11.3.7 [util.smartptr.ownerless]/1, class template <tt>owner_less</tt> synopsis as indicated. The intent is to replace the 
	currently required inheritance-rules by associated type-rules:
<p>
1 The class template <tt>owner_less</tt> allows ownership-based mixed comparisons of shared and weak pointers.
<p>
<blockquote><pre>
namespace std {
  template&lt;class T&gt; struct owner_less;

  template&lt;class T&gt; struct owner_less&lt;shared_ptr&lt;T&gt; &gt;
    <del>: binary_function&lt;shared_ptr&lt;T&gt;, shared_ptr&lt;T&gt;, bool&gt;</del>
  {
    typedef bool result_type;
    <ins>typedef shared_ptr&lt;T&gt; first_argument_type;</ins>
    <ins>typedef shared_ptr&lt;T&gt; second_argument_type;</ins>
    bool operator()(shared_ptr&lt;T&gt; const&amp;, shared_ptr&lt;T&gt; const&amp;) const;
    bool operator()(shared_ptr&lt;T&gt; const&amp;, weak_ptr&lt;T&gt; const&amp;) const;
    bool operator()(weak_ptr&lt;T&gt; const&amp;, shared_ptr&lt;T&gt; const&amp;) const;
  };
  
  template&lt;class T&gt; struct owner_less&lt;weak_ptr&lt;T&gt; &gt;
    <del>: binary_function&lt;weak_ptr&lt;T&gt;, weak_ptr&lt;T&gt;, bool&gt;</del>
  {
    typedef bool result_type;
    <ins>typedef weak_ptr&lt;T&gt; first_argument_type;</ins>
    <ins>typedef weak_ptr&lt;T&gt; second_argument_type;</ins>
    bool operator()(weak_ptr&lt;T&gt; const&amp;, weak_ptr&lt;T&gt; const&amp;) const;
    bool operator()(shared_ptr&lt;T&gt; const&amp;, weak_ptr&lt;T&gt; const&amp;) const;
    bool operator()(weak_ptr&lt;T&gt; const&amp;, shared_ptr&lt;T&gt; const&amp;) const;
  };
}  
</pre></blockquote>
<p>
</li>
<li>Change 23.6.1 [map]/2, class template <tt>map::value_compare</tt> as indicated. The intent is to replace the 
	currently required inheritance-rules by associated type-rules:
<p>
<blockquote><pre>
namespace std {
  template &lt;class Key, class T, class Compare = less&lt;Key&gt;,
    class Allocator = allocator&lt;pair&lt;const Key, T&gt; &gt; &gt;
  class map {
  public:
    [..]
   
    class value_compare
      <del>: public binary_function&lt;value_type,value_type,bool&gt;</del> {
    friend class map;
    protected:
      Compare comp;
      value_compare(Compare c) : comp(c) {}
    public:
      <ins>typedef value_type first_argument_type;</ins>
      <ins>typedef value_type second_argument_type;</ins>
      <ins>typedef bool result_type;</ins>      
      bool operator()(const value_type&amp; x, const value_type&amp; y) const {
        return comp(x.first, y.first);
      }
    };
    
    [..]
</pre></blockquote>
<p>
</li>
<li>Change 23.6.2 [multimap]/2, class template <tt>multimap::value_compare</tt> as indicated. The intent is to replace the 
	currently required inheritance-rules by associated type-rules:
<p>
<blockquote><pre>
namespace std {
  template &lt;class Key, class T, class Compare = less&lt;Key&gt;,
    class Allocator = allocator&lt;pair&lt;const Key, T&gt; &gt; &gt;
  class multimap {
  public:
    [..]
   
    class value_compare
      <del>: public binary_function&lt;value_type,value_type,bool&gt;</del> {
    friend class multimap;
    protected:
      Compare comp;
      value_compare(Compare c) : comp(c) {}
    public:
      <ins>typedef value_type first_argument_type;</ins>
      <ins>typedef value_type second_argument_type;</ins>
      <ins>typedef bool result_type;</ins>      
      bool operator()(const value_type&amp; x, const value_type&amp; y) const {
        return comp(x.first, y.first);
      }
    };
    
    [..]
</pre></blockquote>
<p>
</li>
</ol>
<p>
</body></html>