相关内容:
- 如果一个类将
()
运算符重载为成员函数,这个类就称为函数对象类,这个类的对象就是函数对象。函数对象是一个对象,但是使用的形式看起来像函数调用,实际上也执行了函数调用,因而得名。 ()
是目数不限的运算符,因此重载为成员函数时,有多少个参数都可以。- 重载函数调用操作符的类,其对象常称为函数对象(
function object
),即它们是行为类似函数的对象,也叫仿函数(functor
),其实就是重载“()
”操作符,使得类对象可以像函数那样调用。
注意: - 1.函数对象(仿函数)是一个类,不是一个函数。
- 2.函数对象(仿函数)重载了”
()
”操作符使得它可以像函数一样调用。
假定某个类有一个重载的operator()
,而且重载的operator()
要求获取一个参数,我们就将这个类称为“一元仿函数”(unary functor
);相反,如果重载的operator()
要求获取两个参数,就将这个类称为“二元仿函数”(binary functor
)。
为什么要使用函数对象?
因为函数对象可以记录状态。详细的讲,函数指针在STL
算法中的应用虽然能够增加算法的通用性,但是在实际应用中我们发现它有一个致命的缺点:函数患有严重的健忘症——它只会认认真真地完成一个数据处理过程,至于上一次函数执行时的一些状态数据,它一点记忆都没有。这就让它无法应用在那些需要对每次的执行状态信息进行维护的场景。例如,无法在for_each()
算法中应用单独的一个函数来计算容器中的所有数据的和,因为它无法得知上一次的结果是多少,也就无法在其基础上进行累加。这时,就该函数换上另外一件马甲——函数对象了。代码相关内容:
- 重载函数调用操作符;
- 函数对象:定义了调用操作符的类,其对象称为“函数对象”
- 谓词:如果一个函数对象的返回值是
bool
,则称其为谓词 - 一元函数对象(如果函数对象有一个参数,称其为一元函数对象);一元谓词;(如果函数对象只有一个参数,且返回值为
bool
,则称其为一元谓词; - 二元函数对象;二元谓词(如果返回为
bool
函数,则称其为二元谓词);一元谓词与一元函数对象:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
using namespace std;
template<typename numberType>
struct IsMultiple // 用来判断 element 是否是 m_Divisor 的整数倍
{
numberType m_Divisor;
// 构造函数;
IsMultiple(const numberType& divisor)
{
m_Divisor = divisor;
}
// 一元谓词
bool operator() (const numberType& element) const
{
return ((element % m_Divisor) == 0);
}
};
int main()
{
vector<int> vecIntegers;
for (int i = 33; i <= 100; ++i)
{
vecIntegers.push_back(i);
}
IsMultiple<int> a(4);
vector<int>::iterator iElement; // 用来存放返回值的迭代器;
iElement = find_if(vecIntegers.begin(), vecIntegers.end(), a);
if (iElement != vecIntegers.end())
{
cout << "第一个4的整数倍的数是:" << *iElement << endl;
}
return 0;
}代码执行结果:
二元谓词:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
using namespace std;
// 定义二元谓词;实现功能:将字符串全部转化为小写;
class CCompareStringNoCase
{
public:
bool operator() (const string& str1, const string& str2) const
{
string str1LowerCase;
str1LowerCase.resize(str1.size());
transform(str1.begin(), str1.end(), str1LowerCase.begin(), tolower); // 调用STL算法将 str1 全部转换为小写;
string str2LowerCase;
str2LowerCase.resize(str2.size());
transform(str2.begin(), str2.end(), str2LowerCase.begin(), tolower); // 调用STL算法将 str2 全部转换为小写;
return (str1LowerCase < str2LowerCase);
}
};
int main()
{
//set<string> names;
set<string,CCompareStringNoCase> names; // 增加二元谓词,实现不分大小写都能进行查找的功能;
names.insert("Tina");
names.insert("jim");
names.insert("HTL2018");
names.insert("Sam");
names.insert("hello");
set<string, CCompareStringNoCase>::iterator iNameFound = names.find("htl2018");
if (iNameFound != names.end())
{
cout << "找到了!" << *iNameFound << endl;
}
else
{
cout << "没找到!" << *iNameFound << endl;
}
return 0;
}代码执行结果:
参考链接:
C++函数对象详解(附带实例)
C++ STL 之 函数对象
你好,C++(72)11.2.1 定义一个函数对象