- predicate function problems for general generic functions
- Method one: Common functions as arguments
BOOL GT6 (conststring// Determine if string length is greater than 6{ return6 ;} Vector<string
Since the COUNT_IF algorithm runs a function with only one formal parameter and returns a bool, this variable cannot be used as a function parameter for the length of the string determined by 6, so such a function can only be defined as the length of the dead judge.
- Method Two: Use a Function object
For classes that define call operators, objects become function objects, that is, they are objects that behave like functions, as follows
class gt_cls{public: 0): Length (n) {} booloperator () (conststring &s) >= length;} Private : std::string= count_if (Word.begin (), Word.end (), Gt_cls (6
You can change the value of 6 in Gt_cls (6) above in order to achieve the purpose of calculating different lengths.
- Method Three: function adapters that use standard library function objects and function objects
The standard library function object is defined in the header file functional, such as
For the sort function, we can have
Sort (Word.begin (), Word.end (), greater<string> ()); Sort containers in descending order
In the standard library function object, except for unary minus and logical non, the other is a two-element function object with two operands.
For a predicate function with a generic function, a unary function object that requires an operand
At this point, you can use the function adapter of the function object, the function adapter is divided into two kinds,
1) Binder (binder): Converts a two-tuple function object to a unary function object by binding an operand to a given value. bind1st, binds the given value to the first argument of a two-tuple function object, bind2nd binds the given value to the second argument of a two-tuple function.
2) Negation: It will reverse the truth of the predicate object. Not1 the truth of the unary function and not2 the truth of the two-dollar function.
Such as:
Count_if (Vec.begin (), Vec.end (), bind2nd (greater_equal<int6)); // determine if the value is greater than or equal to 6 count_if (Vec.begin (), Vec.end (), Not1 (bind2nd (greater_equal<int.6)); // judgment value less than 6 count_if (Vec.begin (), Vec.end (), bind2nd (less <int6)); // judgment value less than 6
Of course, there is no way to solve this problem with count_if and function objects, because the left operand of the COUNT_IF predicate function is a string, and the second argument of the binding is int, which cannot be compared.
Instead of using count_if, we can use the IF (Greater_equal (Str.size (), 6)) to determine and then do the related operations.
- Method Four: Lamda expression
Count_if (Words.begin (), Words.end (), [SZ] (conststring &s) {return s.size () >=sz})
SZ is a variable that has been assigned before use
- Method Five: Use the c++11 new standard bind function
The BIND function is a new generic function adapter defined by the C++11 standard
bool check_size (conststring &s,string:: Size_type sz) { return s.size () >=66));
Check6 (s), equivalent to calling Check_size (s,6);
Bind (Check_size, _1, 6)
_n represents the location of the parameters in the generated callable object (here, check6), _1 is the first parameter of the generated callable object, _2 is the second argument; _n is a placeholder
Where _n (here is _1) is defined in the namespace named placeholders, and this namespace is defined in the Std namespace, so there should be an appropriate using declaration before using _1
using std::p laceholders::_1
Of course, in order to simplify, do not write all the required _n, can
using namespace std::p laceholders
Note 2.