C++ STL functional 頭文件與bind1st、bind2nd函數

C++ STL < functional >頭文件與bind1st、bind2nd函數


前言

我們經常使用的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) );

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章