<!--
    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>Non-Member Functions</TITLE>
<LINK REL=StyleSheet HREF="../rw.css" TYPE="text/css" TITLE="Apache stdcxx Stylesheet"></HEAD>
<BODY BGCOLOR=#FFFFFF>
<A HREF="22-6.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="VII.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>22.7 Non-Member Functions</H2>
<A NAME="2271"><H3>22.7.1 Binary Operators</H3></A>
<A NAME="idx472"><!></A>
<P>Class <B><I><A HREF="../stdlibref/valarray.html">valarray</A></I></B> provides a large block of binary operators that allow a program to apply these operators to two <B><I>valarray</I></B>s or to a <B><I>valarray</I></B> and a <SAMP>T</SAMP> value, where the <SAMP>T</SAMP> can occur on the left- or right-hand side of the expression. As you'd expect, these operators do not modify either of their arguments, but instead return a new <B><I>valarray</I></B> containing the result of the operation. Each version that takes two <B><I>valarray</I></B> arguments returns the result of applying the operation to the corresponding elements of the arrays. The versions with a <SAMP>T&amp;</SAMP> argument return a <B><I>valarray</I></B> whose elements result from applying the operation to each element in the <B><I>valarray</I></B> argument along with the <SAMP>T&amp;</SAMP> argument. See the <B><I>valarray</I></B> entry in the <A HREF="../stdlibref/noframes.html"><I>Apache C++ Standard Library Reference Guide</I></A> for a complete list of binary operators.</P>
<P>Arithmetic and bitwise operators return a <B><I><A HREF="../stdlibref/valarray.html">valarray</A></I></B> of <SAMP>T</SAMP>. Logical operators return a <B><I>valarray&lt;bool&gt;</I></B>, where each element represents the comparison of corresponding elements in two <B><I>valarray</I></B>s or the comparison of each element in an array with a particular value. For example:</P>

<UL><PRE>
int a[3] = {1,2,3};
int b[3] = {0,1,4};
std::valarray&lt;int&gt; v1(a,3);
std::valarray&lt;int&gt; v2(b,3); 
std::valarray&lt;int&gt; v3(0,3);
std::valarray&lt;bool&gt; v4(false,3);
v3 = v1 + v2;                      // v3 = {1,3,7}
v4 = v1 == v2;                     // v4 = {false,false,false}
v4 = v1 &lt; v2;                      // v4 = {false,false,true}
</PRE></UL>
<A NAME="2272"><H3>22.7.2 Transcendental Functions</H3></A>
<A NAME="idx473"><!></A>
<P>Class <B><I><A HREF="../stdlibref/valarray.html">valarray</A></I></B> also provides 20 transcendental functions, four of which are overloads. Each function returns a new <B><I>valarray</I></B> that contains elements resulting from the application of the transcendental function to each element in the <B><I>valarray</I></B> passed as an argument. See the <B><I>valarray</I></B> entry in the <A HREF="../stdlibref/noframes.html"><I>Apache C++ Standard Library Reference Guide</I></A> for a complete list of transcendental functions. </P>
<P>The following example squares each of the elements of an array:</P>

<UL><PRE>
using std::pow;

float a[3] = {2.0, 4.0, 16.0};
std::valarray&lt;float&gt; v(a,3);            // v = {2.0, 4.0, 16.0}
std::valarray&lt;float&gt; v2(0.0,3);         // v2 = {0.0, 0.0, 0.0}
v2 = std::pow(v,2.0);                   // v2 = {4.0, 16.0, 256.0 }
</PRE></UL>


<BR>
<HR>
<A HREF="22-6.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="VII.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>
