BDE 4.14.0 Production release
|
Provide a wrapping iterator that invokes a functor on dereference.
This component implements a class template, bdlb::TransformIterator
, that stores an underlying iterator and a one-argument functor. Iterator operations are passed through to the underlying iterator, with the exception of dereference. For dereference, the functor is invoked on the result of dereferencing the underlying iterator, and the result of the functor invocation is returned. This component also implements a utility class, bdlb::TransformIteratorUtil
, that provides a function template for creating TransformIterator
objects.
The templates expect two parameters. The first parameter, designated FUNCTOR
, is the type of a callable object that can be invoked with a single argument. When compiling with C++03, this type must be either a function pointer or otherwise have a type from which bslmf::ResultType
can determine the result type of invoking the functor (see bslmf_resulttype ). The second parameter, designated ITERATOR
, is the type of an object that models an iterator from which values may be obtained, i.e., a type such that bsl::iterator_traits<ITERATOR>
exists and for which typename bsl::iterator_traits<ITERATOR>::iterator_category
derives from bsl::input_iterator_tag
(see bslstl_iterator ). Note that object pointer types qualify.
Note that bdlb::TransformIterator
is more useful in C++11 or later than in C++03, because lambdas can be used as function objects to match a FUNCTOR
of type bsl::function<RETURN_TYPE(INPUT_TYPE)>
.
This section illustrates intended use of this component.
Suppose we have a shopping list of products and we want to compute how much it will cost to buy selected items. We can use bdlb::TransformIterator
to do the computation, looking up the price of each item.
First, we set up the price list:
Then, we set up our shopping list:
Next, we create a functor that will return a price given a product. The following rather prolix functor at namespace scope is necessary for C++03:
Then, we create the functor object. In C++11 or later, the explicit functor class above is unnecessary since we can use a lambda:
Now, we need a pair of transform iterators to process our grocery list. We can use TransformIteratorUtil::make
to create those iterators, avoiding the need to explicitly name types. We create the iterators and process the list in one step, as follows:
Finally, we verify that we have the correct total:
In the previous example, we did not explicitly name our iterator type. We may want to do so, however, if we intend to reuse iterators, or store them in data structures. We will rework the previous example using explicitly typed iterators. We also demonstrate how a single iterator type can deal with multiple functors.
First, we notice that we have two different functor types depending on whether we compile as C++03 or C++11. To abstract away the difference, we will use a bsl::function
functor type that is conformable to both:
Then, we create a pair of these iterators to traverse our list:
Now, we add up the prices of our groceries:
Finally, we verify that we have the correct total:
Suppose we have a sequence of numbers and we would like to sum their absolute values. We can use bdlb::TransformIterator
for this purpose.
First, we set up the numbers:
Then, we need a functor that will return the absolute value of a number. Rather than write a functor object, we can use a simple pointer to function as a functor:
Next, we create the transform iterators that will convert a number to its absolute value. We need iterators for both the beginning and end of the sequence:
Now, we compute the sum of the absolute values of the numbers:
Finally, we verify that we have computed the sum correctly: