本文主要介紹了c++中函數對象的基本概念,以及stl中自帶的常用的函數對象(包括一元函數對象和二元的函數對象)。然後以binder1st和binder2nd爲例以代碼爲示例,簡單的使用方法。然後爲了加深對函數對象的理解,自己根據類模板和函數模板編寫了一個test_binder1st類模板和test_bind1st函數模板,用以實現stl中binder1st和bind1st的功能。
目錄
函數對象的簡介
函數對象就是重載了“()”運算符的類的對象,這樣的話,對象就可以像函數一樣使用。如下面的一段代碼:
#include "stdafx.h"
#include <iostream>
#include <string>
#include <memory>
#pragma warning(disable:4996)
using namespace std;
class test_add{
public:
int operator () (int a, int b)
{
return a + b;
}
};
class test_sub{
public:
int operator () (int a, int b)
{
return a - b;
}
};
int main(int argc, char *argv[])
{
int a = 10;
int b = 20;
test_add add;
test_sub sub;
cout << "a+b= " << add(a, b) << endl;
cout << "a-b= " << sub(a, b) << endl;
return 0;
}
我們在自定義的類中首先重載了“()”運算符,這樣,在使用時定義兩個對象add和sub,然後就可以直接向函數那樣add(a,b),sub(a,b).下面是測試的結果。
a+b= 30
a-b= -10
請按任意鍵繼續. . .
以上是自定義的類,裏面重載“()”運算符。實際上stl中有現成的函數對象可供調用,如需要實現上述的功能,直接調用stl中自帶的即可,如下代碼片段。測試結果和上面的代碼一樣的。
int a = 10;
int b = 20;
minus<int> int_min;
plus<int> int_plus;
cout << "a+b= " << int_plus(a, b) << endl;
cout << "a-b= " << int_min(a, b) << endl;
c++中stl自帶常用的函數對象
除了上面兩個實現加減功能的函數對象,實際上stl自帶了很多函數對象供大家使用。常用的如下,並附帶測試結果。
#include "stdafx.h"
#include <iostream>
#include <functional>
#pragma warning(disable:4996)
using namespace std;
int main(int argc, char *argv[])
{
int a = 10;
int b = 20;
cout << "a= " << a << endl;
cout << "b= " << b << endl;
cout << endl;
plus<int> int_plus;
cout << "a+b= " << int_plus(a, b) << endl;
minus<int> int_min;
cout << "a-b= " << int_min(a, b) << endl;
negate<int> int_neg;
cout << "-a= " << int_neg(a) << endl;
cout << "-b= " << int_neg(b) << endl;
multiplies<int> int_multi;
cout << "a*b= " << int_multi(a, b) << endl;
divides<int> int_div;
cout << "a/b = " << int_div(a, b) << endl;
cout << "b/a = " << int_div(b, a) << endl;
modulus<int> int_mod;
cout << "a%b = " << int_mod(a, b) << endl;
cout << "b/a = " << int_mod(b, a) << endl;
equal_to<int> int_equ;//if = return 1 else return 0
cout << "a!=b " << int_equ(a, b) << endl;
cout << "(b-a) = a " << int_equ(int_min(b, a), a) << endl;
not_equal_to<int> int_not_equ;//
cout << "not_equ a!=b " << int_not_equ(a, b) << endl;
cout << "not_equ (b-a) = a " << int_not_equ(int_min(b, a), a) << endl;
greater<int> int_gre;
cout << "a>b " << int_gre(a, b) << endl;
cout << "b>a " << int_gre(b, a) << endl;
greater_equal<int> int_gre_equ;//>or=
cout << "b-a = a " << int_gre_equ(int_min(b, a), a) << endl;
less<int> int_less;
cout << "less a<b " << int_less(a, b) << endl;
cout << "less b<a " << int_less(b, a) << endl;
less_equal<int> int_less_equ;//<or=
cout << "b-a = a " << int_less_equ(int_min(b, a), a) << endl;
logical_and<int> int_logical_and;
cout << "a&&b = " << int_logical_and(a, b) << endl;
logical_or<int> int_logical_or;
cout << "a||b = " << int_logical_or(a, b) << endl;
logical_not<int> int_logical_not;
cout << "!a = " << int_logical_not(a) << endl;
cout << "!0 = " << int_logical_not(0) << endl;
cout << "!-1 = " << int_logical_not(-1) << endl;
return 0;
}
binder1st ,binder2nd使用方法
基於是上面的使用,stl中還有將二元的函數對象變爲一元的函數對象的函數適配器,下面的例子就是說明,函數適配器的使用方法。這種用法常見於,其中一個參數固定的,自由一個參數是變動的,那麼爲了安全起見,就用這種方法可以減少誤操作。
#include "stdafx.h"
#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>
#pragma warning(disable:4996)
using namespace std;
int main(int argc, char *argv[])
{
int a = 10;
int b = 20;
binder1st<plus<int>> b1st_plus = bind1st(plus<int>(), 10);
binder1st<minus<int>> b1st_minus = bind1st(minus<int>(), 10);
cout << "10+b=" << b1st_plus(b) << endl;
cout << "10-5=" << b1st_minus(5) << endl;
binder2nd<plus<int>> b2nd_plus = bind2nd(plus<int>(), 10);
binder2nd<minus<int>> b2nd_minus = bind2nd(minus<int>(), 10);
cout << "b+10=" << b2nd_plus(b) << endl;
cout << "5-10=" << b2nd_minus(5) << endl;
vector<int> v1;
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
}
//使用count_if獲得容器v1中大於或等於4的個數
int count = count_if(v1.begin(),v1.end(),bind1st(less_equal<int>(),4));
cout << "bind1st v1 >= 4 count=" << count << endl;
count = count_if(v1.begin(), v1.end(), bind2nd(greater_equal<int>(), 4));
cout << "bind2nd v1 >= 4 count=" << count << endl;
return 0;
}
自定義函數適配器的代碼例子
#include "stdafx.h"
#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>
#pragma warning(disable:4996)
using namespace std;
template<typename oper_fun, typename param>
class test_binder1st{
public:
test_binder1st(oper_fun operation, param first_param)
{
oper = operation;
first = first_param;
}
param operator ()(param second)
{
return oper(first, second);
}
private:
oper_fun oper;
param first;
};
template<typename oper_fun, typename param>
test_binder1st<oper_fun, param> test_bind1st(oper_fun operation, param first)
{
return test_binder1st<oper_fun, param>(operation, first);//調用的是上面test_binder1st的構造函數
}
int main(int argc, char *argv[])
{
int a = 10;
int b = 20;
test_binder1st<plus<int>, int> b1st_plus = test_bind1st(plus<int>(), 10);
test_binder1st<minus<int>, int> b1st_minus = test_bind1st(minus<int>(), 10);
cout << "10+b=" << b1st_plus(b) << endl;
cout << "10-5=" << b1st_minus(5) << endl;
vector<int> v1;
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
}
//使用count_if獲得容器v1中大於或等於4的個數
int count = count_if(v1.begin(),v1.end(),test_bind1st(less_equal<int>(),4));
cout << "bind1st v1 >= 4 count=" << count << endl;
return 0;
}