前言
我们经常使用的std::less, std::greater , 也是public 继承了binary_function<int,int,bool>
- binary_function 二元函数
- unary_function 一元函数
template <typename T1, typename T2>
struct myless : public binary_function<T1, T2, bool>
{
bool operator()(const T1 &lhs, const T2 &rhs)
{
return lhs < rhs;
}
};
void test0()
{
//当作类函数使用
vector<int> vec{3, 1, 2, 5, 4};
sort(vec.begin(), vec.end(), myless<int, int>());
for (auto &e : vec)
{
cout << e << endl;
}
//使用binary_function特性
myless<int, int>::first_argument_type first = 1;
myless<int, int>::second_argument_type second = 2;
myless<int, int>::result_type ret;
ret = myless<int, int>()(first, second);
cout << "ret:" << ret << endl;
}
一.用二元函数(binary_function)判断输入的两个数是否相等
class Compare : public std::binary_function<int, int, bool>
{
public:
bool operator()(int a, int b)
{
return a == b;
}
};
void test1()
{
Compare::first_argument_type first;
Compare::second_argument_type second;
Compare::result_type ret;
Compare comp;
cout << "please input two integers:" << endl;
cin >> first >> second;
ret = comp(first, second);
if (ret)
{
cout << "equal" << endl;
}
else
{
cout << "not equal " << endl;
}
}
二.用一元函数(unary_function)判断是否为奇数
struct isOdd : public unary_function<int, bool>
{
bool operator()(int Elem)
{
return Elem % 2 == 1;
}
};
void test2()
{
isOdd::argument_type arg = 1;
isOdd::result_type ret;
ret = isOdd()(arg);
cout << (ret ? "is Odd" : "is Even") << endl;
}
三.bind1st bind2nd
template <class Operation, class T>
binder1st<Operation> bind1st (const Operation& op, const T& x)
{
return binder1st<Operation>(op, typename Operation::first_argument_type(x));
}
其中参数operation代表进行的操作,x则是对操作中的first_argument_type进行赋值,接下来是binder1st函数:
template <class Operation> class binder1st
: public unary_function <typename Operation::second_argument_type,
typename Operation::result_type>
{
protected:
Operation op;
typename Operation::first_argument_type value;
public:
binder1st ( const Operation& x,
const typename Operation::first_argument_type& y) : op (x), value(y) {}
typename Operation::result_type
operator() (const typename Operation::second_argument_type& x) const
{ return op(value,x); }
};
通过上面的代码可以看出, bind1st的作用是绑定first_argument 为 x, bind2nd的作用也就是绑定second_argument
从下面的实例可以明白,bind函数返回的是一个函数类,并且对参数进行了绑定,这样我们就不需要在使用算法的过程中自己去写函数了,直接使用bind即可
注意:Operation必须继承binary_function<T,T,bool>类,才能进行bind绑定,也就是说,Operation不能是简单的bool返回值函数,而必须是一个继承了binary_function类的函数类
void test3()
{
vector<int> vec{10, 20, 30, 40, 50, 10};
//输出等于10的元素个数
cout << count_if(vec.begin(), vec.end(), bind1st(less_equal<int>(), 10)) << endl;
//输出大于等于30的元素的个数
cout << count_if(vec.begin(), vec.end(), bind2nd(greater_equal<int>(),30)) << endl;
//输出小于等于30的元素的个数
cout << count_if(vec.begin(), vec.end(), bind2nd(less_equal<int>(),30)) << endl;
}
//自定义Operation进行绑定操作
struct Student{
string name;
int score;
};
template<typename T>
struct scoreLess:public binary_function<T,T,bool>{
bool operator()(const T& lhs, const T& rhs)const {
return lhs.score < rhs.score;
}
};
template<typename T>
struct displayStudent:public binary_function<T,int,bool>{
bool operator()(const T& lhs, const int& rhs)const{
if (lhs.score > rhs){
cout << "Student Name:" << lhs.name << ", Score:" << lhs.score << endl;
return true;
}
return false;
}
};
void test4(){
Student s;
s.name = "standard Student";
s.score = 75;
vector<Student> vec{{"s1", 60}, {"s2", 70}, {"s3", 80}, {"s4", 90}};
//统计平均分以下的学生个数
cout << count_if(vec.begin(), vec.end(), bind2nd(scoreLess<Student>(), s)) << endl;
//打印平均分以上的学生信息
for_each(vec.begin(), vec.end(), bind2nd(displayStudent<Student>(), 75) );
}