mirror of
https://gitlab.com/fbb-git/cppannotations
synced 2024-11-18 10:06:54 +01:00
4a51c31ab9
git-svn-id: https://cppannotations.svn.sourceforge.net/svnroot/cppannotations/trunk@23 f6dd340e-d3f9-0310-b409-bdd246841980
92 lines
5.1 KiB
Text
92 lines
5.1 KiB
Text
The hi(arithmetic function object) arithmetic function objects support the
|
|
standard i(arithmetic operations): i(addition), i(subtraction),
|
|
i(multiplication), i(division), i(modulus) and i(negation). These predefined
|
|
arithmetic function objects invoke the corresponding operator of the
|
|
associated data type. For example, for addition the function object
|
|
tt(plus<Type>) hi(plus<>()) is available. If we set tt(type) to tt(size_t)
|
|
then the tt(+) operator for tt(size_t) values is used, if we set tt(type) to
|
|
tt(string), then the tt(+) operator for strings is used. For example:
|
|
verbinclude(stl/examples/plus.cc)
|
|
Why is this useful? Note that the function object can be used with all
|
|
kinds of data types (not only with the predefined datatypes), in which the
|
|
particular operator has been overloaded. Assume that we want to perform an
|
|
operation on a common variable on the one hand and, on the other hand, in turn
|
|
on each element of an array. E.g., we want to compute the sum of the elements
|
|
of an array; or we want to concatenate all the strings in a text-array. In
|
|
situations like these the function objects come in handy. As noted before, the
|
|
function objects are heavily used in the context of the generic algorithms, so
|
|
let's take a quick look ahead at one of them.
|
|
|
|
One of the generic algorithms is called ti(accumulate()). It visits all
|
|
elements implied by an iterator-range, and performs a requested binary
|
|
operation on a common element and each of the elements in the range, returning
|
|
the accumulated result after visiting all elements.
|
|
For example, the following program accumulates all command line arguments,
|
|
and prints the final string:
|
|
verbinclude(stl/examples/plusaccumulate.cc)
|
|
The first two arguments define the (iterator) range of elements to visit,
|
|
the third argument is tt(string()). This anonymous string object provides an
|
|
initial value. It could as well have been initialized to
|
|
centt(string("All concatenated arguments: "))
|
|
in which case the tt(cout) statement could have been a simple
|
|
verb(
|
|
cout << result << endl;
|
|
)
|
|
Then, the operator to apply is tt(plus<string>()). Note here that a
|
|
constructor is called: it is em(not) tt(plus<string>), but rather
|
|
tt(plus<string>()). The final concatenated string is returned.
|
|
|
|
Now we define our own class tt(Time), in which the
|
|
ti(operator+()) has been overloaded. Again, we can apply the predefined
|
|
function object tt(plus), now tailored to our newly defined datatype, to add
|
|
times:
|
|
verbinclude(stl/examples/classtypeplus.cc)
|
|
Note that all member functions of tt(Time) in the above source are inline
|
|
functions. This approach was followed in order to keep the example relatively
|
|
small and to show explicitly that the tt(operator+=()) function may be an
|
|
inline function. On the other hand, in real life tt(Time)'s tt(operator+=())
|
|
should probably not be made inline, due to its size.
|
|
|
|
Considering the previous discussion of the tt(plus) function object, the
|
|
example is pretty straightforward. The class tt(Time) defines a constructor,
|
|
it defines an insertion operator and it defines its own tt(operator+()),
|
|
adding two time objects.
|
|
|
|
In tt(main()) four tt(Time) objects are stored in a
|
|
tt(vector<Time>) object. Then, the tt(accumulate()) generic algorithm is
|
|
called to compute the accumulated time. It returns a tt(Time) object, which
|
|
is inserted in the tt(cout ostream) object.
|
|
|
|
While the first example did show the use of a em(named) function object,
|
|
the last two examples showed the use of emi(anonymous) objects which were
|
|
passed to the (tt(accumulate())) function.
|
|
|
|
The following arithmetic objects are available as predefined objects:
|
|
itemization(
|
|
iti(plus<>()): as shown, this object's tt(operator()()) member calls
|
|
tt(operator+()) as a i(binary operator), passing it its two parameters,
|
|
returning tt(operator+())'s return value.
|
|
iti(minus<>()): this object's tt(operator()()) member calls
|
|
ti(operator-()) as a binary operator, passing it its two parameters and
|
|
returning tt(operator-())'s return value.
|
|
iti(multiplies<>()): this object's tt(operator()()) member calls
|
|
ti(operator*()) as a binary operator, passing it its two parameters and
|
|
returning tt(operator*())'s return value.
|
|
iti(divides<>()): this object's tt(operator()()) member calls
|
|
ti(operator/()), passing it its two parameters and
|
|
returning tt(operator/())'s return value.
|
|
iti(modulus<>()): this object's tt(operator()()) member calls
|
|
ti(operator%()), passing it its two parameters and
|
|
returning tt(operator%())'s return value.
|
|
iti(negate<>()): this object's tt(operator()()) member calls
|
|
tt(operator-()) as a unary operator, passing it its parameter and
|
|
returning the unary tt(operator-())'s return value.
|
|
)
|
|
An example using the unary tt(operator-()) follows, in
|
|
which the ti(transform()) generic algorithm is used to toggle the signs of all
|
|
elements in an array. The tt(transform()) generic algorithm expects two
|
|
iterators, defining the range of objects to be transformed, an iterator
|
|
defining the begin of the destination range (which may be the same iterator as
|
|
the first argument) and a function object defining a unary operation for the
|
|
indicated data type.
|
|
verbinclude(stl/examples/negate.cc)
|