Function Objects: Additional Features
STL6Func1°. Define a function object (function object, functor) — a structure less_abs with the operator () — a constant member function having two integer parameters a and b and returning the result of the comparison |a| < |b|. The structure less_abs should be derived from the standard generic structure function<bool(int, int)>. Using the function object less_abs and the sort algorithm, sort the initial vector V of integers in ascending order of their absolute values. Note. If the compiler does not support the C++11 standard, then use the generic structure binary_function<int, int, bool> as the ancestor of the structure less_abs.
STL6Func2°. Given a vector V of integers. Using a call to the adjacent_find algorithm, find the initial pair of elements (a, b) of the vector V for which the inequality |a| ≥ |b| holds, and output the found pair of elements in ascending order of their indices. If there are no suitable pairs, output the single number 0. To search for the required pair, use the function adapter not2 (inverter), applying it to the function object less_abs described in STL6Func1. Note. For the possibility of applying a function adapter to a function object, it is necessary that, firstly, this object is derived from the corresponding base class (in this case, the class function or binary_function) and, secondly, has an implementation of the operator () as a constant member function. For direct application of a function object (without function adapters), the listed conditions are not mandatory.
STL6Func3°. Given an integer K (> 0) and a vector V containing integers. Using the function object less_abs described in STL6Func1, together with the function adapter bind (binder) in the remove_if algorithm, and the erase method, remove from the vector V all elements whose absolute value is less than K. Output the size of the transformed vector V and its elements. To enable the use of the parameter _1 of the adapter bind, the directive using namespace std::placeholders must be added to the program, specifying it after the directive #include <functional>. Note. If the compiler does not support the C++11 standard, then instead of the universal binder bind, use the specialized adapter-binder for the second parameter bind2nd.
STL6Func4°. Given an integer K (> 0) and a vector V containing integers. Using the function object less_abs described in STL6Func1, together with the function adapter bind in the find_if algorithm, find and output the last element of the vector whose absolute value is greater than K. If the vector does not contain the required elements, output 0. Note. If the compiler does not support the C++11 standard, then instead of the universal binder bind, use the specialized adapter-binder for the first parameter bind1st.
STL6Func5°. Given an integer K (> 0) and a vector V containing integers. Using the function object less_abs described in task STL6Func1, to which the inverter not2 and the binder bind are sequentially applied, construct a predicate for checking the condition K ≥ |x| and use it as the last parameter of the count_if algorithm to find the number of elements of the vector whose absolute value is less than or equal to K. Notes. (1) If the compiler does not support the C++11 standard, then instead of the binder bind, use bind1st.
(2) When using the binder bind, the order of calling the adapters is important: first not2, then bind. Note that the old variants of binders (bind1st and bind2nd) can be combined with inverters in any order.
(3) In this task, it is possible to do without the inverter (which provides the transformation of a strict inequality into a non-strict one), since for the correct solution it is sufficient to use a predicate with a strict inequality of the form K + 1 < |x|. However, the described technique may be useful in similar situations with more complex function objects.
STL6Func6°. Given vectors V1 and V2 with the same number of elements — integers. Using the transform algorithm and the standard function object multiplies, transform the vector V2 by multiplying its elements by the corresponding elements of the vector V1.
STL6Func7°. Given an integer K and a vector V containing integers. Using the transform algorithm and the standard function object minus with the binder bind, transform the initial vector by decreasing the values of all its elements by the value K. Note. If the compiler does not support the C++11 standard, then instead of the binder bind, use bind2nd.
STL6Func8°. Given an integer K and two vectors V1 and V2 of the same size, containing integers. Using the transform algorithm and the standard function objects plus and multiplies with nested binders bind, transform the vector V1 by multiplying each of its elements by the number K and adding to the result the value of the corresponding element of the vector V2. Note. The specialized binders bind1st and bind2nd do not allow constructing the required function object based on standard ones. If the compiler does not support the C++11 standard, then the task can be solved without creating new function objects by using twofold application of the transform algorithm.
STL6Func9°. Define a structure point with integer members x, y and a string member s. It is assumed that the string member s does not contain spaces. The order relation for this structure is defined as follows: A < B if A.x < B.x or (A.x == B.x and A.y < B.y). Implement this order relation as a constant member function bool operator<(const point& b) const. Also, implement the operation istream& operator>>(istream& is, point& p), which sequentially reads from the input stream is the members x, y, and s of the structure p, and the operation ostream& operator<<(ostream& os, const point& p), which writes all members of the structure p to the output stream os (the members are written in the same order in which they are read; a space is inserted between them). Given a text file named Name containing text representations of elements of the structure described above. Using the input iterator istream_iterator, fill a vector V of type point with these data. Using the stable_sort algorithm, sort the obtained data taking into account the given order relation and, using the copy algorithm and the output iterator ostream_iterator, write the sorted vector to the original file, replacing its previous content (points with the same coordinates will be arranged in the same order as in the original file, since the stable_sort algorithm provides a stable sort). Each point should be displayed on a new line. Notes. (1) The operations >> and << allow using standard stream input and output iterators for input and output of objects of type point.
(2) Due to the explicitly defined operator < for the structure point, it is not required to specify a function object for comparing vector elements in the sorting algorithm: by default, the function object less<point>() is used, which is an object wrapper for the operator <.
(3) It should be noted that for sorting in decreasing order one cannot use the (syntactically valid) function object not2(less<point>()), because the result will be an object for non-strict comparison (a >= b), which cannot be used in algorithms related to sorting (the condition of strict comparison is violated for it: if a is "less than" b, then b should not be simultaneously "less than" a). In such a situation, one should use the object greater<point>(), having previously defined the operator > for the class point.
STL6Func10°. Given a text file named Name containing text representations of elements of the structure point implemented in STL6Func9. Supplement the structure point by including in it the conversion operator operator string(), which returns a string with the text representations of the members x, y, s, separated by spaces. Also, describe a logical member function is_positive(), which returns the value true if the numbers x and y are positive. Using the replace_copy_if algorithm together with the input iterator istream_iterator<point> and the output iterator ptout_iterator<string>, replace those elements from the original text file that have positive members x and y with the object point (0, 0, "A"), and output the text representations of all elements of the transformed set. Do not use auxiliary containers. As the predicate parameter of the algorithm replace_copy_if, use the member function is_positive, converted into a function object using the function adapter mem_fn(&point::is_positive). Notes. (1) If the compiler does not support the C++11 standard, then instead of the adapter mem_fn, use its old variant mem_fun_ref. Note that the adapter mem_fn can also be applied when the algorithm processes a container containing pointers to objects (while in this situation, instead of mem_fun_ref, another function adapter must be used: mem_fun).
(2) When implementing the conversion operator to a string, it is convenient to use the string stream ostringstream from the header file <sstream>.
(3) If a conversion operator to a string is defined in a class or structure, then objects of this class (structure) can be specified as parameters of the functions Show and ShowLine, which provide output of data to the debug section of the taskbook window.
STL6Func11°. Given a text file named Name containing text representations of elements of the structure point implemented in STL6Func9. Using an auxiliary vector V of type point and the stable_partition algorithm, regroup the elements in the initial set by moving to the beginning of the set all elements that are less than the point with coordinates (0, 0). Output the text representations of all elements of the transformed set (see STL6Func10). As the parameter — function object in the algorithm stable_partition, use the object less<point>(), applying the binder bind to it. Note. If the compiler does not support the C++11 standard, then instead of the binder bind, use bind2nd.
STL6Func12°. Given text files named Name1 and Name2 containing text representations of elements of the structure point implemented in STL6Func9. The files contain the same number of elements. Define the addition operation for point objects, which adds the values of the corresponding fields (both numeric and string), as an overloaded function point operator+(const point& a, const point& b). Read data from files Name1 and Name2 into vectors V1 and V2 respectively. Using the transform algorithm with the parameter plus<point>(), transform the elements of the vector V1 by adding to them the corresponding elements of the vector V2. Write the transformed vector V1 to the file Name1, replacing its previous content.
STL6Func13°. Given a text file named Name containing text representations of elements of the structure point implemented in STL6Func9. Using an auxiliary vector V of type point and the transform algorithm with the function object plus (see STL6Func12) and the binder bind, transform the initial set by adding to each of its elements the object point (10, 20, "Z"). Output the text representations of all elements of the transformed set (see STL6Func11). Note. If the compiler does not support the C++11 standard, then instead of the binder bind, use bind2nd.
STL6Func14°. Given an integer K and text files named Name1 and Name2 containing text representations of elements of the structure point implemented in STL6Func10. The files contain the same number of elements. Supplement the structure point by adding to it a member function point mult(int k), which performs multiplication of a point object by a number: the call p.mult(k) returns an object of type point whose members x and y are equal to k*p.x and k*p.y respectively, and the member s matches the string p.s. Read data from files Name1 and Name2 into vectors V1 and V2. Using the transform algorithm with a suitable function object containing two binders bind, the object plus (see STL6Func12) and the member function mult, transform the elements of the vector V1 by multiplying each of them by the number K and adding to the result of the multiplication the corresponding element of the vector V2. Output the text representations of all elements of the transformed vector V1 (see STL6Func11). Notes. (1) To bind the member function mult using bind, it is sufficient to specify the reference &point::mult as the parameter of the binder; the adapter mem_fn (see STL6Func10) does not need to be applied to the reference in this case (although it is not prohibited).
(2) The specialized binders bind1st and bind2nd do not allow constructing the required function object based on standard ones (compare with STL6Func8). If the compiler does not support the C++11 standard, then the task can be solved without creating new function objects by using twofold application of the transform algorithm. In this case, to perform multiplication of the elements of the first vector by K, it is necessary to use the binder bind2nd for the object mem_fun_ref(&point::mult) (the use of the adapter mem_fun_ref in this case is mandatory).
|