<!--
    Licensed to the Apache Software  Foundation (ASF) under one or more
    contributor  license agreements.  See  the NOTICE  file distributed
    with  this  work  for  additional information  regarding  copyright
    ownership.   The ASF  licenses this  file to  you under  the Apache
    License, Version  2.0 (the  License); you may  not use  this file
    except in  compliance with the License.   You may obtain  a copy of
    the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the  License is distributed on an  "AS IS" BASIS,
    WITHOUT  WARRANTIES OR CONDITIONS  OF ANY  KIND, either  express or
    implied.   See  the License  for  the  specific language  governing
    permissions and limitations under the License.

    Copyright 1999-2007 Rogue Wave Software, Inc.
-->

<HTML>
<HEAD>
<TITLE>&lt;utility&gt;</TITLE>
<LINK REL=StyleSheet HREF="../rw.css" TYPE="text/css" TITLE="Apache stdcxx Stylesheet"></HEAD>
<BODY BGCOLOR=#FFFFFF>
<A HREF="use-facet.html"><IMG SRC="images/bprev.gif" WIDTH=20 HEIGHT=21 ALT="Previous file" BORDER=O></A><A HREF="noframes.html"><IMG SRC="images/btop.gif" WIDTH=56 HEIGHT=21 ALT="Top of Document" BORDER=O></A><A HREF="booktoc.html"><IMG SRC="images/btoc.gif" WIDTH=56 HEIGHT=21 ALT="Contents" BORDER=O></A><A HREF="tindex.html"><IMG SRC="images/bindex.gif" WIDTH=56 HEIGHT=21 ALT="Index page" BORDER=O></A><A HREF="valarray-h.html"><IMG SRC="images/bnext.gif" WIDTH=25 HEIGHT=21 ALT="Next file" BORDER=O></A><DIV CLASS="DOCUMENTNAME"><B>Apache C++ Standard Library Reference Guide</B></DIV>
<H2>&lt;utility&gt;</H2>
<P><B>Library:</B>&nbsp;&nbsp;<A HREF="2-4.html">General utilities</A></P>

<PRE><HR><B><I>Header</I></B><HR></PRE>

<UL>
<LI><A HREF="#sec1">Local Index</A></LI>
<LI><A HREF="#sec2">Summary</A></LI>
<LI><A HREF="#sec3">Synopsis</A></LI>
<LI><A HREF="#sec4">See Also</A></LI>
<LI><A HREF="#sec5">Standards Conformance</A></LI>
</UL>
<A NAME="sec1"><H3>Local Index</H3></A>
No Entries
<A NAME="sec2"><H3>Summary</H3></A>
<P>The header <SAMP>&lt;utility&gt;</SAMP> is part of the General utilities library of the C++ Standard Library. It defines the class template <B><I><A HREF="pair.html">pair</A></I></B>, a helper function template <SAMP>make_pair()</SAMP>, a set of relational operators that C++ programs may use to perform equality and inequality tests on specializations of <B><I>pair</I></B>, and, in the namespace <SAMP>rel_ops</SAMP>, the function templates <SAMP>operator!=()</SAMP>, <SAMP>operator&gt;()</SAMP>, <SAMP>operator&lt;=()</SAMP>, and <SAMP>operator&gt;=()</SAMP>.</P>
<A NAME="sec3"><H3>Synopsis</H3></A>

<PRE>namespace std {
  namespace rel_ops {
    template&lt;class T&gt; bool operator!=(const T&amp;, const T&amp;);
    template&lt;class T&gt; bool operator&gt; (const T&amp;, const T&amp;);
    template&lt;class T&gt; bool operator&lt;=(const T&amp;, const T&amp;);
    template&lt;class T&gt; bool operator&gt;=(const T&amp;, const T&amp;);
  }

  template &lt;class T1, class T2&gt; 
  struct <SAMP><A HREF="pair.html">pair</A></SAMP>;
  template &lt;class T1, class T2&gt;
  bool operator==(const pair&lt;T1, T2&gt;&amp;, const pair&lt;T1, T2&gt;&amp;);
  template &lt;class T1, class T2&gt;
  bool operator&lt; (const pair&lt;T1, T2&gt;&amp;, const pair&lt;T1, T2&gt;&amp;);
  template &lt;class T1, class T2&gt;
  bool operator!=(const pair&lt;T1, T2&gt;&amp;, const pair&lt;T1, T2&gt;&amp;);
  template &lt;class T1, class T2&gt;
  bool operator&gt; (const pair&lt;T1, T2&gt;&amp;, const pair&lt;T1, T2&gt;&amp;);
  template &lt;class T1, class T2&gt;
  bool operator&gt;=(const pair&lt;T1, T2&gt;&amp;, const pair&lt;T1, T2&gt;&amp;);
  template &lt;class T1, class T2&gt;
  bool operator&lt;=(const pair&lt;T1, T2&gt;&amp;, const pair&lt;T1, T2&gt;&amp;);
  template &lt;class T1, class T2&gt; pair&lt;T1, T2&gt;
  make_pair (const T1&amp;, const T2&amp;);
}
</PRE>
<A NAME="sec4"><H3>See Also</H3></A>
<P><B><I><A HREF="pair.html">pair</A></I></B>, <A HREF="operators.html">Operators</A></P>
<A NAME="sec5"><H3>Standards Conformance</H3></A>
<P><I>ISO/IEC 14882:1998 -- International Standard for Information Systems --Programming Language C++, Section 20.2</I></P>

<BR>
<HR>
<A HREF="use-facet.html"><IMG SRC="images/bprev.gif" WIDTH=20 HEIGHT=21 ALT="Previous file" BORDER=O></A><A HREF="noframes.html"><IMG SRC="images/btop.gif" WIDTH=56 HEIGHT=21 ALT="Top of Document" BORDER=O></A><A HREF="booktoc.html"><IMG SRC="images/btoc.gif" WIDTH=56 HEIGHT=21 ALT="Contents" BORDER=O></A><A HREF="tindex.html"><IMG SRC="images/bindex.gif" WIDTH=56 HEIGHT=21 ALT="Index page" BORDER=O></A><A HREF="valarray-h.html"><IMG SRC="images/bnext.gif" WIDTH=20 HEIGHT=21 ALT="Next file" BORDER=O></A>

<!-- Google Analytics tracking code -->
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
    _uacct = "UA-1775151-1";
    urchinTracker();
</script>
<!-- end of Google Analytics tracking code -->

</BODY>
</HTML>
