<!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 (Rev 1)</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: N3198=10-0188<br>
Date: 2010-11-11<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> (Revision 1)</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>
This paper attempts to resolve issues related to several currently required class-derivation relations
from specializations of <tt>unary_function</tt> and <tt>binary_function</tt>.
<p>
For details of the rationale of this paper see <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2010/n3145.html">n3145</a>.
<p>
<h2><a name="Discussion"></a>Discussion</h2>
<p>
During the Batavia 2010 meeting it was agreed on the general direction suggested by
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2010/n3145.html">n3145</a>. 
There was also one part of the proposal that did not reach consensus, namely the deprecation 
of the negators <tt>not1()</tt>, <tt>not2()</tt>, and their corresponding return types,
because there are currently no actual replacement forms (except usage of lambda expressions).
<p>
This revision of <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2010/n3145.html">n3145</a>
does exclude this particular part, and adapts the current definitions of <tt>unary_negate</tt>
and <tt>binary_negate</tt> in the same way as for the remaining affected function object types.
<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>20.8.9, negators</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>Change the template definitions in sub-clause [negators] 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 Predicate&gt;
class unary_negate
  <del>: public unary_function&lt;typename Predicate::argument_type,bool&gt;</del> {
public:
  <ins>typedef typename Predicate::argument_type argument_type;</ins>
  <ins>typedef bool result_type;</ins>
  explicit unary_negate(const Predicate&amp; pred);
  bool operator()(const typename Predicate::argument_type&amp; x) const;
};
	
[..]

template &lt;class Predicate&gt;
class binary_negate
  <del>: public binary_function&lt;typename Predicate::first_argument_type,
  typename Predicate::second_argument_type, bool&gt;</del> {
public:
  <ins>typedef typename Predicate::first_argument_type first_argument_type;</ins>
  <ins>typedef typename Predicate::second_argument_type second_argument_type;</ins>
  <ins>typedef bool result_type;</ins>
  explicit binary_negate(const Predicate&amp; pred);
  bool operator()(const typename Predicate::first_argument_type&amp; x,
    const typename Predicate::second_argument_type&amp; y) const;
};	
</pre></blockquote>
</li>
<li>Following the new sub-clause [depr.lib.base] and before the current D.9 [depr.lib.binders] 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>