我们都知道汉语和英语中是有谓词(谓语)这个概念的,汉语中的“是”,英语中的“is”等等。那么计算机语言是否也有谓词呢?那当然是有的!
计算机语言中的谓词和函数以及函数对象有关,函数大家都了解,但函数对象,可能很多人就不知道了,所以接下来我们重点将的就是函数对象。
- 写在前面
- 概念及使用
- 函数对象中的谓词
- 内建函数对象
- 算术仿函数
- 关系仿函数
- 逻辑仿函数
- 结束语
函数对象的概念:
- 重载 *** 作符()的类,其对象常称为函数对象
- 函数对象使用重载的()时,行为类似函数调用,因此也叫仿函数
本质:函数对象(仿函数)是一个类,而不是一个函数
使用:
- 函数对象可以像普通函数那样调用,可以有参数和返回值
- 函数对象超出普通函数之处是,函数对象可以有自己的状态(就是对象的成员变量)
- 函数对象可以作为参数传递
下面我们从一个简单的例子里,了解函数对象的具体使用
#includeusing namespace std; class myPrint { public: int count;//函数对象的状态,用来记录函数使用的次数 myPrint() :count(0) {} void operator()(string str) //重载() *** 作符 { cout << str; ++count; } }; void doPrint(myPrint& mp, string str)//函数对象作为参数传递 { mp(str); } int main() { myPrint Print; Print("hello 函数对象n"); Print("hello 函数对象n"); doPrint(Print, "hello 仿函数"); cout << "函数对象调用的次数:" << Print.count << endl; }
例子非常简单,就没必要分析了,打印输出如下:
函数对象中的谓词hello 函数对象
hello 函数对象
hello 仿函数
函数对象调用的次数:3
下面我们正式了解一下谓词
谓词概念:
- 返回值是bool类型的函数或函数对象称为谓词
- 如果operator()接收一个参数,就叫一元谓词
- 如果operator()接收两个参数,就叫二元谓词
谓词的用途:
在C++ STL的内置算法中有很多函数都是有谓词这个参数的,比如大家常用的sort()排序算法,它的参数列表如下:
void sort<_Ranlt>(const_Ranlt_First, const_Ranlt_Last, _Pr_Pred);
它的第三个参数_Pr_Pred就是谓词,这个参数可以不用传,默认升序排序,但如果你想要降序排序,这个谓词参数就必须要传了。
使用:
下面我们就通过排序的这个例子来了解谓词的使用
#include#include #include #include using namespace std; class compare { public: bool operator()(int v1,int v2) { return v1 > v2; } }; void Print(int a[], int n) { for (int i = 0; i < 10; ++i) { cout << a[i] << " "; } } int main() { int arr[10] = { 8,5,7,2,9,4,1,0,3,6 };//乱序的数组 cout << "升序打印:"; sort(arr, arr + 10); Print(arr, 10); //添加谓词参数 cout << "n降序打印:"; sort(arr, arr + 10, compare());//compare()是匿名函数对象 Print(arr, 10); }
例子中谓词的参数有两个,显然就是二元谓词了。
有一点需要注意,因为代码中compare是个类,传入sort中时需要在后面加(),compare()是匿名函数对象。
如果compare只是一个函数,那就不用加(),直接传入compare即可。
打印输出如下:
内建函数对象升序打印:0 1 2 3 4 5 6 7 8 9
降序打印:9 8 7 6 5 4 3 2 1 0
概念:C++STL中内建了一些函数对象,也就是说别人已经给你写好了一些函数对象,你直接拿去用就行了
分类:
- 算术仿函数
- 关系仿函数
- 逻辑仿函数
用法:
- 这些仿函数所产生的对象,用法和一般函数完全相同
- 使用内建函数对象的时候,需要包含头文件 #include
原型:
- template
T plus 加法仿函数 - template
T minus 减法仿函数 - template
T multiplies 乘法仿函数 - template
T divides 除法仿函数 - template
T modulus 取模仿函数 - template
T negate 取反仿函数
功能:
- 实现四则运算
- 其中negate是一元运算,其他都是二元运算
使用:
看一个算术仿函数的实例,使用起来非常简单
#include#include using namespace std; int main() { plus p; cout << "加法仿函数运算结果:" << p(123, 456) << endl; modulus md; cout << "取模仿函数运算结果:" << md(35, 14) << endl; negate n;//一元运算,下面只传一个参数 cout << "取反仿函数运算结果:" << n(10) << endl; }
打印输出:
关系仿函数加法仿函数运算结果:579
取模仿函数运算结果:7
取反仿函数运算结果:-10
原型:
-
template
bool equal_to 等于 -
template
bool not_equal_to 不等于 -
template
bool greater 大于 -
template
bool greater_equal 大于等于 -
template
bool less 小于 -
template
bool less_equal 小于等于
用途:
如果只是简单的比较两个数的大小,我们完全没必要用到关系仿函数,完全可以使用关系运算符>、=、<等来判断。但关系仿函数可以充当C++STL算法中的谓词,也就是说,不用我们自己写谓词了,直接用就完了,记得要加头文件哦 #include
使用:
#include#include #include using namespace std; int main() { int arr[10] = { 5,9,0,7,6,4,8,3,1,2 }; //降序排序 sort(arr, arr + 10, greater ()); for (int i = 0; i < 10; ++i) { cout << arr[i] << " "; } }
是不是方便多了,不用我们自己写降序排序的排序规则,直接用greater
输出打印:
逻辑仿函数9 8 7 6 5 4 3 2 1 0
原型:
- template
bool logical_and 逻辑与 - template
bool logical_or 逻辑或 - template
bool logical_not 逻辑非
使用:
逻辑仿函数基本上是用不到的,简单地了解一下即可
结束语好了,本篇到此结束,你的点赞、评论、关注、收藏都是对我最大的支持,谢谢!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)