<!--
    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>Functions</TITLE>
<LINK REL=StyleSheet HREF="../rw.css" TYPE="text/css" TITLE="Apache stdcxx Stylesheet"></HEAD>
<BODY BGCOLOR=#FFFFFF>
<A HREF="3.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="3-2.html"><IMG SRC="images/bnext.gif" WIDTH=25 HEIGHT=21 ALT="Next file" BORDER=O></A><DIV CLASS="DOCUMENTNAME"><B>Apache C++ Standard Library User's Guide</B></DIV>
<H2>3.1 Functions</H2>
<A NAME="idx43"><!></A>
<P>A number of algorithms provided in the C++ Standard Library accept functions as arguments. A simple example is the algorithm <SAMP>std::for_each()</SAMP>, which invokes a function, passed as an argument, on each value held in a container. For example, the following code fragment applies the <SAMP>printElement()</SAMP> function to produce output describing each element in a list of integer values:</P>

<UL><PRE>
void printElement(int value)
{
   std::cout &lt;&lt; "The list contains " &lt;&lt; value &lt;&lt; std::endl;
}

int main() 
{
   std::list&lt;int&gt; aList;
      ...
   std::for_each(aList.begin(), aList.end(), printElement);
}
</PRE></UL>
<P><I>Binary functions</I> take two arguments, and are often applied to values from two different sequences. For example, suppose we have a list of strings and a list of integers. For each element in the first list we wish to replicate the string the number of times given by the corresponding value in the second list. We can perform this easily using the function <SAMP>std::transform()</SAMP> from the C++ Standard Library. First, we define a binary function with the desired characteristics:</P>

<UL><PRE>
std::string stringRepeat(const std::string&amp; base, int number)
// replicate base the given number of times
{
   std::string result;   // initially the result is empty
   while (number--) result += base;
   return result;
}
</PRE></UL>
<P>The following call on <SAMP>std::transform()</SAMP> then produces the desired effect:</P>

<UL><PRE>
std::list&lt;string&gt; words;
std::list&lt;int&gt; counts;
   ...
std::transform(words.begin(), words.end(), 
               counts.begin(), words.begin(), stringRepeat);
</PRE></UL>
<P>Transforming the strings <SAMP>"one"</SAMP>, <SAMP>"two"</SAMP>, <SAMP>"three"</SAMP> with the values <SAMP>3</SAMP>, <SAMP>2</SAMP>, <SAMP>3</SAMP> would yield the result <SAMP>"oneoneone"</SAMP>, <SAMP>"twotwo"</SAMP>, <SAMP>"threethreethree"</SAMP>.</P>

<BR>
<HR>
<A HREF="3.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="3-2.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>
