一下內(nèi)容轉(zhuǎn)自http://blog.csdn.net/thinkingmyl/archive/2009/08/17/4456419.aspx
1.仿函數(shù)
1.1 定義:
本質(zhì)是一個(gè)類,是一個(gè)像使用函數(shù)一樣直接名稱+括號(hào)就可以調(diào)用的類,事實(shí)上就是一個(gè)重載了operator()函數(shù)的類。
1.2 目的:
具有內(nèi)部狀態(tài)的功能,這是函數(shù)所不能比擬的。
1.3 例子:
#include "stdafx.h"
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
using std::string;
class Person
{
public:
Person(string init): name(init)
{
}
string name;
};
class PersonCriterion //這個(gè)就是仿函數(shù),用于比較兩個(gè)名字的長(zhǎng)短
{
public:
bool operator() (const Person& t1, const Person& t2)
{
std::cout << "第" << ++count << "次調(diào)用" << std::endl; //通過(guò)他可以很清晰地知道函數(shù)調(diào)用多少次
return t1.name.length() < t2.name.length();
}
private:
static int count;
};
int PersonCriterion::count = 0;
int _tmain(int argc, _TCHAR* argv[])
{
std::vector<Person> iv;
iv.push_back(Person("one"));
iv.push_back(Person("two"));
iv.push_back(Person("three"));
iv.push_back(Person("four"));
//將類像函數(shù)一樣將指針傳遞進(jìn)去,sort將調(diào)用 PersonCriterion::operator() 對(duì)vector進(jìn)行排序。
std::sort(iv.begin(), iv.end(), PersonCriterion() );
for (std::vector<Person>::iterator it = iv.begin();
it != iv.end();
++it)
{
std::cout << (*it).name << " ";
}
return 0;
}
最后的結(jié)果可能根據(jù)STL的實(shí)作可能會(huì)有所區(qū)別。
2 函數(shù)配接器:
2.1 定義:
函數(shù)配接器是一種特殊的仿函數(shù)。能夠?qū)⒎潞瘮?shù)和另外一個(gè)仿函數(shù)結(jié)合起來(lái)的函數(shù)或者說(shuō)是一個(gè)將仿函數(shù)作為參數(shù)的仿函數(shù)。預(yù)先定義好的函數(shù)配接器有
bind1st(op, value),
bind2nd(op, value),
not1(op),
not2(op)
2.2 分類:
函數(shù)適配器有兩種:
針對(duì)一般函數(shù)(非成員函數(shù))而設(shè)計(jì)的函數(shù)適配器
針對(duì)成員函數(shù)而設(shè)計(jì)的函數(shù)適配器
2.3 針對(duì)一般函數(shù)(非成員函數(shù))而設(shè)計(jì)的函數(shù)適配器:
這種是我們最經(jīng)常使用的用法。通過(guò)函數(shù)適配器對(duì)一個(gè)參數(shù)進(jìn)行綁定。
#include "stdafx.h"
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
using std::string;
class Person
{
public:
Person(string init): name(init)
{
}
string name;
};
bool shorter (const Person& t1, const Person& t2)
{
return t1.name.length() < t2.name.length();
}
int _tmain(int argc, _TCHAR* argv[])
{
std::vector<Person> iv;
iv.push_back(Person("one"));
iv.push_back(Person("two"));
iv.push_back(Person("three"));
iv.push_back(Person("four"));
//將函數(shù)指針傳遞進(jìn)去
std::sort(iv.begin(), iv.end(), shorter);
for (std::vector<Person>::iterator it = iv.begin();
it != iv.end();
++it)
{
std::cout << (*it).name << " ";
}
return 0;
}
2.4 針對(duì)成員函數(shù)而設(shè)計(jì)的函數(shù)配接器
這里所說(shuō)的成員函數(shù)不包括operator(). 這種用法不多見。是通過(guò)mem_fun_ref進(jìn)行轉(zhuǎn)換,將原本針對(duì)某個(gè)元素的函數(shù)調(diào)用轉(zhuǎn)為調(diào)用被傳遞變量(*itr itr為iv的迭代器)的成員函數(shù)。
#include "stdafx.h"
#include <vector>
#include <string>
#include <functional>
#include <algorithm>
#include <iostream>
using std::string;
class Person
{
public:
Person(string init): name(init)
{
}
//以成員函數(shù)調(diào)用,故可忽略const Person& t1
bool shorter(const Person& t2) const
{
std::cout << "第" << ++count << "次調(diào)用" << std::endl;
return name.length() < t2.name.length();
}
string name;
static int count;
};
int Person::count = 0;
int _tmain(int argc, _TCHAR* argv[])
{
std::vector<Person> iv;
iv.push_back(Person("one"));
iv.push_back(Person("two"));
iv.push_back(Person("three"));
iv.push_back(Person("four"));
std::sort(iv.begin(), iv.end(), std::mem_fun_ref(&Person::shorter) );
for (std::vector<Person>::iterator it = iv.begin();
it != iv.end();
++it)
{
std::cout << (*it).name << " ";
}
return 0;
}
2.5 可以使用函數(shù)配接器的自定義仿函數(shù)
函數(shù)配接器只能用在系統(tǒng)仿函數(shù)(例如less)中,如果我們想要我們的仿函數(shù)能夠使用函數(shù)配接器,必須然類從unary_function或
binary_function派生而來(lái)。因?yàn)楹瘮?shù)適配器里面用到了參數(shù)的特定成員(例如T1::argument_type,
T1::result_type),所以我們只要在類繼承列表里添加
public std::unary_function<T1,T1>
或public std::binary_function<T1,T2,T1>即可