1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302
|
<HTML>
<!--
-- Copyright (c) 1996-1999
-- Silicon Graphics Computer Systems, Inc.
--
-- Permission to use, copy, modify, distribute and sell this software
-- and its documentation for any purpose is hereby granted without fee,
-- provided that the above copyright notice appears in all copies and
-- that both that copyright notice and this permission notice appear
-- in supporting documentation. Silicon Graphics makes no
-- representations about the suitability of this software for any
-- purpose. It is provided "as is" without express or implied warranty.
--
-- Copyright (c) 1994
-- Hewlett-Packard Company
--
-- Permission to use, copy, modify, distribute and sell this software
-- and its documentation for any purpose is hereby granted without fee,
-- provided that the above copyright notice appears in all copies and
-- that both that copyright notice and this permission notice appear
-- in supporting documentation. Hewlett-Packard Company makes no
-- representations about the suitability of this software for any
-- purpose. It is provided "as is" without express or implied warranty.
--
-->
<Head>
<Title>Function Objects</Title>
<!-- Generated by htmldoc -->
</HEAD>
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
ALINK="#ff0000">
<IMG SRC="CorpID.gif"
ALT="SGI" HEIGHT="43" WIDTH="151">
<!--end header-->
<BR Clear>
<H1>Function Objects</H1>
<Table CellPadding=0 CellSpacing=0 width=100%>
<TR>
<TD Align=left><Img src = "functors.gif" Alt="" WIDTH = "194" HEIGHT = "38" ></TD>
<TD Align=right><Img src = "overview.gif" Alt="" WIDTH = "194" HEIGHT = "38" ></TD>
</TR>
<TR>
<TD Align=left VAlign=top><b>Category</b>: functors</TD>
<TD Align=right VAlign=top><b>Component type</b>: overview</TD>
</TR>
</Table>
<h3>Summary</h3>
A <i>Function Object</i>, or <i>Functor</i> (the two terms are synonymous)
is simply any object that can be called as if it is a function.
An ordinary function is a function object, and so is a function pointer;
more generally, so is an object of a class that defines
<tt>operator()</tt>.
<h3>Description</h3>
The basic function object concepts are <A href="Generator.html">Generator</A>,
<A href="UnaryFunction.html">Unary Function</A>, and <A href="BinaryFunction.html">Binary Function</A>: these describe,
respectively, objects that can be called as <tt>f()</tt>, <tt>f(x)</tt>, and
<tt>f(x,y)</tt>. (This list could obviously be extended to <i>ternary function</i>
and beyond, but, in practice, no STL algorithms require function
objects of more than two arguments.) All other function object
concepts defined by the STL are refinements of these three.
<P>
Function objects that return <tt>bool</tt> are
an important special case.
A <A href="UnaryFunction.html">Unary Function</A> whose return type is <tt>bool</tt> is called a
<A href="Predicate.html">Predicate</A>, and a <A href="BinaryFunction.html">Binary Function</A> whose return type is
<tt>bool</tt> is called a <A href="BinaryPredicate.html">Binary Predicate</A>.
<P>
There is an important distinction, but a somewhat subtle one, between
function objects and <i>adaptable function objects</i>. <A href="#1">[1]</A> In general, a
function object has restrictions on the type of its argument. The
type restrictions need not be simple, though: <tt>operator()</tt> may be
overloaded, or may be a member template, or both. Similarly, there
need be no way for a program to determine what those restrictions are.
An adaptable function object, however, does specify what the argument
and return types are, and provides nested <tt>typedef</tt>s so that those
types can be named and used in programs. If a type <tt>F0</tt> is a model of
<A href="AdaptableGenerator.html">Adaptable Generator</A>, then it must define
<tt>F0::result_type</tt>. Similarly, if <tt>F1</tt> is a model of
<A href="AdaptableUnaryFunction.html">Adaptable Unary Function</A> then it must define
<tt>F1::argument_type</tt> and <tt>F1::result_type</tt>, and if <tt>F2</tt> is a model
of <A href="AdaptableBinaryFunction.html">Adaptable Binary Function</A> then it must define
<tt>F2::first_argument_type</tt>, <tt>F2::second_argument_type</tt>, and
<tt>F2::result_type</tt>.
The STL provides base classes <tt><A href="unary_function.html">unary_function</A></tt> and
<tt><A href="binary_function.html">binary_function</A></tt> to simplify the definition of
<A href="AdaptableUnaryFunction.html">Adaptable Unary Functions</A> and <A href="AdaptableBinaryFunction.html">Adaptable Binary Functions</A>. <A href="#2">[2]</A>
<P>
Adaptable function objects are important because they can be used by
<i>function object adaptors</i>: function objects that transform or
manipulate other function objects. The STL provides many different
function object adaptors, including <tt><A href="unary_negate.html">unary_negate</A></tt> (which returns
the logical complement of the value returned by a particular
<A href="AdaptablePredicate.html">AdaptablePredicate</A>), and <tt><A href="unary_compose.html">unary_compose</A></tt> and
<tt><A href="binary_compose.html">binary_compose</A></tt>, which perform composition of function object.
<P>
Finally, the STL includes many different predefined function
objects, including arithmetic operations
(<tt><A href="plus.html">plus</A></tt>, <tt><A href="minus.html">minus</A></tt>, <tt><A href="times.html">multiplies</A></tt>, <tt><A href="divides.html">divides</A></tt>, <tt><A href="modulus.html">modulus</A></tt>,
and <tt><A href="negate.html">negate</A></tt>), comparisons (<tt><A href="equal_to.html">equal_to</A></tt>, <tt><A href="not_equal_to.html">not_equal_to</A></tt>
<tt><A href="greater.html">greater</A></tt>, <tt><A href="less.html">less</A></tt>, <tt><A href="greater_equal.html">greater_equal</A></tt>, and <tt><A href="less_equal.html">less_equal</A></tt>),
and logical operations (<tt><A href="logical_and.html">logical_and</A></tt>, <tt><A href="logical_or.html">logical_or</A></tt>, and
<tt><A href="logical_not.html">logical_not</A></tt>). It is possible to perform very sophisticated
operations without actually writing a new function object, simply
by combining predefined function objects and function object
adaptors.
<h3>Examples</h3>
Fill a <tt><A href="Vector.html">vector</A></tt> with random numbers. In this example, the function object
is simply a function pointer.
<pre>
<A href="Vector.html">vector</A><int> V(100);
<A href="generate.html">generate</A>(V.begin(), V.end(), rand);
</pre>
<P>
Sort a <tt><A href="Vector.html">vector</A></tt> of <tt>double</tt> by magnitude, <i>i.e.</i> ignoring the elements' signs.
In this example, the function object is an object of a user-defined
class.
<pre>
struct less_mag : public <A href="binary_function.html">binary_function</A><double, double, bool> {
bool operator()(double x, double y) { return fabs(x) < fabs(y); }
};
<A href="Vector.html">vector</A><double> V;
...
<A href="sort.html">sort</A>(V.begin(), V.end(), less_mag());
</pre>
<P>
Find the sum of elements in a <tt><A href="Vector.html">vector</A></tt>. In this example, the function
object is of a user-defined class that has local state.
<pre>
struct adder : public <A href="unary_function.html">unary_function</A><double, void>
{
adder() : sum(0) {}
double sum;
void operator()(double x) { sum += x; }
};
<A href="Vector.html">vector</A><double> V;
...
adder result = <A href="for_each.html">for_each</A>(V.begin(), V.end(), adder()); <A href="#3">[3]</A>
cout << "The sum is " << result.sum << endl;
</pre>
<P>
Remove all elements from a <tt><A href="List.html">list</A></tt> that are greater than 100 and
less than 1000.
<pre>
<A href="List.html">list</A><int> L;
...
<A href="List.html">list</A><int>::iterator new_end =
<A href="remove_if.html">remove_if</A>(L.begin(), L.end(),
<A href="binary_compose.html">compose2</A>(<A href="logical_and.html">logical_and</A><bool>(),
<A href="binder2nd.html">bind2nd</A>(<A href="greater.html">greater</A><int>(), 100),
<A href="binder2nd.html">bind2nd</A>(<A href="less.html">less</A><int>(), 1000)));
L.erase(new_end, L.end());
</pre>
<h3>Concepts</h3>
<UL>
<LI>
<A href="Generator.html">Generator</A>
<LI>
<A href="UnaryFunction.html">Unary Function</A>
<LI>
<A href="BinaryFunction.html">Binary Function</A>
</UL>
<UL>
<LI>
<A href="Predicate.html">Predicate</A>
<LI>
<A href="BinaryPredicate.html">Binary Predicate</A>
</UL>
<UL>
<LI>
<A href="AdaptableGenerator.html">Adaptable Generator</A>
<LI>
<A href="AdaptableUnaryFunction.html">Adaptable Unary Function</A>
<LI>
<A href="AdaptableBinaryFunction.html">Adaptable Binary Function</A>
<LI>
<A href="AdaptablePredicate.html">Adaptable Predicate</A>
<LI>
<A href="AdaptableBinaryPredicate.html">Adaptable Binary Predicate</A>
</UL>
<h3>Types</h3>
<UL>
<LI>
<tt><A href="plus.html">plus</A></tt>
<LI>
<tt><A href="minus.html">minus</A></tt>
<LI>
<tt><A href="times.html">multiplies</A></tt> (formerly called <tt>times</tt>)
<LI>
<tt><A href="divides.html">divides</A></tt>
<LI>
<tt><A href="modulus.html">modulus</A></tt>,
<LI>
<tt><A href="negate.html">negate</A></tt>
<LI>
<tt><A href="equal_to.html">equal_to</A></tt>
<LI>
<tt><A href="not_equal_to.html">not_equal_to</A></tt>
<LI>
<tt><A href="greater.html">greater</A></tt>
<LI>
<tt><A href="less.html">less</A></tt>
<LI>
<tt><A href="greater_equal.html">greater_equal</A></tt>
<LI>
<tt><A href="less_equal.html">less_equal</A></tt>,
<LI>
<tt><A href="logical_and.html">logical_and</A></tt>
<LI>
<tt><A href="logical_or.html">logical_or</A></tt>
<LI>
<tt><A href="logical_not.html">logical_not</A></tt>
<LI>
<tt><A href="subtractive_rng.html">subtractive_rng</A></tt>
</UL>
<UL>
<LI>
<tt><A href="identity.html">identity</A></tt>
<LI>
<tt><A href="project1st.html">project1st</A></tt>
<LI>
<tt><A href="project2nd.html">project2nd</A></tt>
<LI>
<tt><A href="select1st.html">select1st</A></tt>
<LI>
<tt><A href="select2nd.html">select2nd</A></tt>
</UL>
<UL>
<LI>
<tt><A href="unary_function.html">unary_function</A></tt>
<LI>
<tt><A href="binary_function.html">binary_function</A></tt>
</UL>
<UL>
<LI>
<tt><A href="unary_compose.html">unary_compose</A></tt>
<LI>
<tt><A href="binary_compose.html">binary_compose</A></tt>
<LI>
<tt><A href="unary_negate.html">unary_negate</A></tt>
<LI>
<tt><A href="binary_negate.html">binary_negate</A></tt>
<LI>
<tt><A href="binder1st.html">binder1st</A></tt>
<LI>
<tt><A href="binder2nd.html">binder2nd</A></tt>
<LI>
<tt><A href="pointer_to_unary_function.html">pointer_to_unary_function</A></tt>
<LI>
<tt><A href="pointer_to_binary_function.html">pointer_to_binary_function</A></tt>
</UL>
<h3>Functions</h3>
<UL>
<LI>
<tt><A href="unary_compose.html">compose1</A></tt>
<LI>
<tt><A href="binary_compose.html">compose2</A></tt>
<LI>
<tt><A href="unary_negate.html">not1</A></tt>
<LI>
<tt><A href="binary_negate.html">not2</A></tt>
<LI>
<tt><A href="binder1st.html">bind1st</A></tt>
<LI>
<tt><A href="binder2nd.html">bind2nd</A></tt>
<LI>
<tt><A href="ptr_fun.html">ptr_fun</A></tt>
</UL>
<h3>Notes</h3>
<P><A name="1">[1]</A>
The reason for the name "adaptable function object" is that
adaptable function objects may be used by function object adaptors.
<P><A name="2">[2]</A>
The <tt><A href="unary_function.html">unary_function</A></tt> and <tt><A href="binary_function.html">binary_function</A></tt> bases are
similar to the <tt><A href="input_iterator.html">input_iterator</A></tt>, <tt><A href="output_iterator.html">output_iterator</A></tt>,
<tt><A href="forward_iterator.html">forward_iterator</A></tt>, <tt><A href="bidirectional_iterator.html">bidirectional_iterator</A></tt>, and
<tt><A href="random_access_iterator.html">random_access_iterator</A></tt> bases: they are completely empty,
and serve only to provide type information.
<P><A name="3">[3]</A>
This is an example of how to use function objects; it is not
the recommended way of calculating the sum of elements in a vector.
The <tt><A href="accumulate.html">accumulate</A></tt> algorithm is a better way of calculating a sum.
<h3>See also</h3>
<!--start footer-->
<HR SIZE="6">
<A href="http://www.sgi.com/"><IMG SRC="surf.gif" HEIGHT="54" WIDTH="54"
ALT="[Silicon Surf]"></A>
<A HREF="index.html"><IMG SRC="stl_home.gif"
HEIGHT="54" WIDTH="54" ALT="[STL Home]"></A>
<BR>
<FONT SIZE="-2">
<A href="http://www.sgi.com/Misc/sgi_info.html" TARGET="_top">Copyright ©
1999 Silicon Graphics, Inc.</A> All Rights Reserved.</FONT>
<FONT SIZE="-3"><a href="http://www.sgi.com/Misc/external.list.html" TARGET="_top">TrademarkInformation</A>
</FONT>
<P>
</BODY>
</HTML>
|