STL仿函数(二) bind1st,bind2nd

文章目录

      • 前言
      • 一.用二元函数(binary_function)判断输入的两个数是否相等
      • 二.用一元函数(unary_function)判断是否为奇数
      • 三.bind1st bind2nd


前言

我们经常使用的std::less, std::greater , 也是public 继承了binary_function

  • 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类,才能进行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) );

}

你可能感兴趣的:(STL)