一下內容轉自http://blog.csdn.net/thinkingmyl/archive/2009/08/17/4456419.aspx
1.仿函數
1.1 定義:
本質是一個類,是一個像使用函數一樣直接名稱+括號就可以調用的類,事實上就是一個重載了operator()函數的類。
1.2 目的:
具有內部狀態的功能,這是函數所不能比擬的。
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 //這個就是仿函數,用于比較兩個名字的長短
{
public:
bool operator() (const Person& t1, const Person& t2)
{
std::cout << "第" << ++count << "次調用" << std::endl; //通過他可以很清晰地知道函數調用多少次
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"));
//將類像函數一樣將指針傳遞進去,sort將調用 PersonCriterion::operator() 對vector進行排序。
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;
}
最后的結果可能根據STL的實作可能會有所區別。
2 函數配接器:
2.1 定義:
函數配接器是一種特殊的仿函數。能夠將仿函數和另外一個仿函數結合起來的函數或者說是一個將仿函數作為參數的仿函數。預先定義好的函數配接器有
bind1st(op, value),
bind2nd(op, value),
not1(op),
not2(op)
2.2 分類:
函數適配器有兩種:
針對一般函數(非成員函數)而設計的函數適配器
針對成員函數而設計的函數適配器
2.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;
};
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"));
//將函數指針傳遞進去
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 針對成員函數而設計的函數配接器
這里所說的成員函數不包括operator(). 這種用法不多見。是通過mem_fun_ref進行轉換,將原本針對某個元素的函數調用轉為調用被傳遞變量(*itr itr為iv的迭代器)的成員函數。
#include "stdafx.h"
#include <vector>
#include <string>
#include <functional>
#include <algorithm>
#include <iostream>
using std::string;
class Person
{
public:
Person(string init): name(init)
{
}
//以成員函數調用,故可忽略const Person& t1
bool shorter(const Person& t2) const
{
std::cout << "第" << ++count << "次調用" << 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 可以使用函數配接器的自定義仿函數
函數配接器只能用在系統仿函數(例如less)中,如果我們想要我們的仿函數能夠使用函數配接器,必須然類從unary_function或
binary_function派生而來。因為函數適配器里面用到了參數的特定成員(例如T1::argument_type,
T1::result_type),所以我們只要在類繼承列表里添加
public std::unary_function<T1,T1>
或public std::binary_function<T1,T2,T1>即可