<!--
    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>advance()</TITLE>
<LINK REL=StyleSheet HREF="../rw.css" TYPE="text/css" TITLE="Apache stdcxx Stylesheet"></HEAD>
<BODY BGCOLOR=#FFFFFF>
<A HREF="adjacent-find.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="algorithm-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>advance()</H2>
<P><B>Library:</B>&nbsp;&nbsp;<A HREF="2-8.html">Iterators</A></P>

<PRE><HR><B><I>Function</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">Description</A></LI>
<LI><A HREF="#sec5">Example</A></LI>
<LI><A HREF="#sec6">See Also</A></LI>
<LI><A HREF="#sec7">Standards Conformance</A></LI>
</UL>
<A NAME="sec1"><H3>Local Index</H3></A>
No Entries
<A NAME="sec2"><H3>Summary</H3></A>
<P>A function that advances an iterator forward or backward (if available) by a certain distance</P>
<A NAME="sec3"><H3>Synopsis</H3></A>

<PRE>#include &lt;iterator&gt;

namespace std {
  template &lt;class InputIterator, class Distance&gt;
  void advance(InputIterator&amp; i, Distance n);
}
</PRE>
<A NAME="sec4"><H3>Description</H3></A>
<P>The <SAMP>advance()</SAMP> function template allows an iterator to be advanced through a container by some arbitrary distance. For bidirectional and random access iterators, this distance may be negative. For random access iterators, this function uses <SAMP>operator+=()</SAMP> and <SAMP>operator-=()</SAMP> for constant time implementations. For input, forward, and bidirectional iterators, <SAMP>advance()</SAMP> uses <SAMP>operator++()</SAMP> for linear time implementations. <SAMP>advance()</SAMP> also uses <SAMP>operator--()</SAMP> with bidirectional iterators for linear time implementations of negative distances. </P>
<P>If <SAMP>n</SAMP> is positive, <SAMP>advance()</SAMP> increments iterator reference <SAMP>i</SAMP> by <SAMP>n</SAMP>. For&nbsp;negative&nbsp;<SAMP>n</SAMP>, <SAMP>advance()</SAMP> decrements reference <SAMP>i</SAMP>. Remember that <SAMP>advance()</SAMP> accepts a negative argument <SAMP>n</SAMP> for random access and bidirectional iterators only.</P>
<A NAME="sec5"><H3>Example</H3></A>

<UL><PRE>//
// advance.cpp
//

#include &lt;iterator&gt;   // for advance
#include &lt;iostream&gt;   // for cout, endl
#include &lt;list&gt;       // for list



int main ()
{
    // Typedefs for convenience.
    typedef std::list&lt;long, std::allocator&lt;long&gt; &gt; list;
    typedef std::ostream_iterator&lt;list::value_type, char,
                              std::char_traits&lt;char&gt; &gt; os_iter;

    // Initialize a list using an array.
    const list::value_type arr [] = { 3, 4, 5, 6, 7, 8 };
    list l (arr + 0, arr + sizeof arr / sizeof *arr);

    // Declare a list iterator, s.b. a ForwardIterator.
    list::iterator itr = l.begin ();

    // Output the original list.
    std::cout &lt;&lt; "For the list: ";
    std::copy (l.begin (), l.end (), os_iter (std::cout, " "));

    std::cout &lt;&lt; std::endl &lt;&lt; std::endl
          &lt;&lt; "When the iterator is initialized to l.begin ()," 
          &lt;&lt; "\nit points to " &lt;&lt; *itr &lt;&lt; std::endl;

    // operator+ is not available for a ForwardIterator, 
    // so use advance.
    std::advance (itr, 4);
    std::cout 
      &lt;&lt; "\nAfter advance (itr, 4), the iterator points to "
      &lt;&lt; *itr &lt;&lt; std::endl;

    return 0;
}

Program Output:
For the list: 3 4 5 6 7 8 

When the iterator is initialized to l.begin (),
it points to 3

After advance (itr, 4), the iterator points to 7
</PRE></UL>
<A NAME="sec6"><H3>See Also</H3></A>
<P><A HREF="sequences.html">Sequences</A>, <A HREF="randomaccessiterators.html">Random Access Iterators</A>, <SAMP><A HREF="distance.html">distance()</A></SAMP></P>
<A NAME="sec7"><H3>Standards Conformance</H3></A>
<P><I>ISO/IEC 14882:1998 -- International Standard for Information Systems -- Programming Language C++, Section 24.3.4</I></P>

<BR>
<HR>
<A HREF="adjacent-find.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="algorithm-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>
