Today, I used some STL functions when I was doing C ++ Primer Chapter 1 exercise 14th, which completely overturned my views on C ++. In the past, I always thought C ++ was very troublesome. To implement a function, I had to write a bunch of code, which was very complicated. That was the idea of cainiao. Although it is still a cainiao, the level is a little higher than the original one. I learned from the use of STL algorithms today that C ++ can be so concise.
Expand the exercises step by step. The exercises are as follows:
Exercise 14.37 uses the standard library function object and function adapter to define an object:
(A) query all values greater than 1024
(B) search for all strings not greater than pooth
(C) multiply all values by 2
Before doing this, let's briefly introduce the function objects of C ++ and the function adapters provided by the standard library.
In C ++, function objects are classes that call operators to implement certain operations, that is, to overload operator () operator functions, they must be declared as member functions. Function objects are often used as arguments for common algorithms. The standard library defines many function objects for programmers. They are defined in the functional header file, including the arithmetic function object type, relational function object type, and logical function object type, some of these function objects are unary function objects, some are binary function objects. The unary function objects accept one real parameter, and the binary function objects accept two real parameters.
Many standard library algorithms are provided in STL. General standard library algorithms use built-in operations, such as <, =. If you want to use custom operations, you can pass function pointers, however, there is a limit on the number of form parameters of function pointers, which is not very convenient to use. At this time, the function object can play a role. You can use redundant parameters as internal members of the function object and pass the value to the function object during initialization, the purpose of comparison is to call the call operators of function objects.
C ++ provides function adapters to extend the use of function objects. The binary function object must pass two values. If one of the values is known or default, it can be initialized. This function is provided by the biner, bind1st is used to bind the first real parameter of the binary function object, and bind2nd is used to bind the second real parameter of the binary function object. Another adapter is an anti-bot used to reverse the true value of the predicate function object. not1 is used to reverse the unary function object and not2 is used to reverse the binary function.
After briefly introducing the basics, I will return to the exercises to see how STL makes the program concise.
For (a), you can use the bind2nd function adapter and greater <int> function object, as shown below:
[Cpp]
// Find the value greater than 1024 with standard function objects and function adaptor
Int nVal [] = {43, 53,536,497 6, 5307, 32,536,957 };
Size_t size = sizeof (nVal)/sizeof (int );
Cout <"The original value:" <endl;
For (size_t I = 0; I! = Size; ++ I)
Cout <nVal [I] <"";
Cout <endl;
Int * nFind = nVal;
Int toCompare = 1024;
Cout <"The value that greater than" <toCompare <":" <endl;
While (nFind = find_if (nFind, nVal + size, bind2nd (greater <int> (), toCompare )))! = NVal + size)
{
Cout <* nFind <"";
++ NFind;
}
Cout <endl;
For (B), you can use bind2nd function adapter and not_0000_to <string> function object, as shown below:
[Cpp]
// Find string not equal with "pooth"
Const int ARYSIZE = 5;
String sAry [ARYSIZE] = {"abc", "adu", "butterfly", "pooth", "nancy "};
Vector <string> sVec (sAry, sAry + ARYSIZE );
Vector <string >:: iterator sIter = sVec. begin ();
Cout <"The original string:" <endl;
While (sIter! = SVec. end ())
{
Cout <* sIter <"";
++ SIter;
}
Cout <endl;
Cout <"The string that not euqal with \" pooth \ ":" <endl;
SIter = sVec. begin ();
String sToCompare = "pooth ";
While (sIter = find_if (sIter, sVec. end (), bind2nd (not_0000_to <string> (), sToCompare )))! = SVec. end ())
{
Cout <* sIter <"";
++ SIter;
}
Cout <endl;
For (c), bind2nd function adapter, transform, and multiplies <int> can be used for implementation, as shown below:
[Cpp]
Class PrintVal
{
Public:
PrintVal (){}
Void operator () (int & val) const {cout <val <"";}
};
// Multiply all the value by 2
Vector <int> nVec (nVal, nVal + size );
Cout <"The original val:" <endl;
For_each (nVec. begin (), nVec. end (), PrintVal ());
Cout <endl;
Transform (nVec. begin (), nVec. end (), nVec. begin (), bind2nd (multiplies <int> (), 2 ));
Cout <"After multiply by 2:" <endl;
For_each (nVec. begin (), nVec. end (), PrintVal ());
Cout <endl;
Can we see from the above that the code from (a) (B) to (c) is much more concise? by introducing the PrintVal function object and the use of for_each, the amount of code is greatly reduced, make the program look simple and easy to understand.
The code for the entire exercise is as follows:
[Cpp]
# Include <iostream>
# Include <functional>
# Include <algorithm>
# Include <vector>
# Include <string>
Using namespace std;
Class PrintVal
{
Public:
PrintVal (){}
Void operator () (int & val) const {cout <val <"";}
};
Int main ()
{
// Find the value greater than 1024 with standard function objects and function adaptor
Int nVal [] = {43, 53,536,497 6, 5307, 32,536,957 };
Size_t size = sizeof (nVal)/sizeof (int );
Cout <"The original value:" <endl;
For (size_t I = 0; I! = Size; ++ I)
Cout <nVal [I] <"";
Cout <endl;
Int * nFind = nVal;
Int toCompare = 1024;
Cout <"The value that greater than" <toCompare <":" <endl;
While (nFind = find_if (nFind, nVal + size, bind2nd (greater <int> (), toCompare )))! = NVal + size)
{
Cout <* nFind <"";
++ NFind;
}
Cout <endl;
// Find string not equal with "pooth"
Const int ARYSIZE = 5;
String sAry [ARYSIZE] = {"abc", "adu", "butterfly", "pooth", "nancy "};
Vector <string> sVec (sAry, sAry + ARYSIZE );
Vector <string >:: iterator sIter = sVec. begin ();
Cout <"The original string:" <endl;
While (sIter! = SVec. end ())
{
Cout <* sIter <"";
++ SIter;
}
Cout <endl;
Cout <"The string that not euqal with \" pooth \ ":" <endl;
SIter = sVec. begin ();
String sToCompare = "pooth ";
While (sIter = find_if (sIter, sVec. end (), bind2nd (not_0000_to <string> (), sToCompare )))! = SVec. end ())
{
Cout <* sIter <"";
++ SIter;
}
Cout <endl;
// Multiply all the value by 2
Vector <int> nVec (nVal, nVal + size );
Cout <"The original val:" <endl;
For_each (nVec. begin (), nVec. end (), PrintVal ());
Cout <endl;
Transform (nVec. begin (), nVec. end (), nVec. begin (), bind2nd (multiplies <int> (), 2 ));
Cout <"After multiply by 2:" <endl;
For_each (nVec. begin (), nVec. end (), PrintVal ());
Cout <endl;
Return 0;
}
From huagong_adu