#include
using namespace std;
//函数对象(也叫仿函数 functor)
//仿函数 通常不需要构造和析构
class print {
public:
void operator()(string str) {
cout << str << endl;
}
};
void test() {
//调用函数对象:方法1
print ob;
ob("hello world !");
//调用函数对象:方法2
print()("A good day !");
}
int main() {
test();
return 0;
}
函数对象,就是重载小括号;
类对象和括号结合就会出发函数对象调用;
返回值为bool类型的普通函数,做谓词
或仿函数,做谓词。
如果谓词 有一个参数 叫:一元谓词
如果谓词 有二个参数 叫:二元谓词
//一元谓词,查找案例
找到第一个 >30 的元素
#include
#include
using namespace std;
//函数对象(也叫仿函数 functor)
//仿函数 通常不需要构造和析构
class print {
public:
void operator()(string str) {
cout << str << endl;
}
};
void test() {
//调用函数对象:方法1
print ob;
ob("hello world !");
//调用函数对象:方法2
print()("A good day !");
}
//谓词(两种方法,名字一样会报错,稍微区别一下)
//1.返回值为bool类型的普通函数,做谓词;
bool greaterThan30(int value) {
return value > 30;
}
// 2.仿函数,做谓词;
class greaterThan30 {
public:
bool operator()(int value) const{ //const ;如果调用处错误,需要在此处加const
return value > 30;
}
};
void test2() {
vector v;
v.push_back(10);
v.push_back(50);
v.push_back(60);
v.push_back(30);
v.push_back(10);
//find_it条件查找; 找到满足条件的元素,就返回迭代器
vector::iterator ret;
//1.普通函数,做谓词; 函数名
ret = find_if(v.begin(),v.end(),greaterThan30);
// 2.仿函数,做谓词;类名称+()
//ret = find_if(v.begin(), v.end(), greaterThan30());
if (ret != v.end())
cout << "找到元素为:" << *ret << endl;
else
cout << "元素未找到" << endl;
}
int main() {
test2();
return 0;
}
返回值为bool类型的普通函数,做谓词;
调用的时候,只写函数名,不需括号和参数;
(加括号就成真的函数调用了,这里是谓词,不是函数调用)
//1.普通函数,做谓词; 函数名
ret = find_if(v.begin(),v.end(),greaterThan30);
仿函数,做谓词;
调用的时候,记得括号
// 2.仿函数,做谓词;类名称+()
//ret = find_if(v.begin(), v.end(), greaterThan30());
//二元谓词(两种方法,名字一样会报错,稍微区别一下)
//1.返回值为bool类型的普通函数,做谓词;
bool greaterInt(int val1, int val2) {
return val1 < val2;
}
// 2.仿函数,做谓词;
class greaterInt2 {
public:
bool operator()(int val1, int val2)const {
return val1 < val2;
}
};
void printVector(vector& v) {
vector::iterator it = v.begin();
for (; it != v.end(); it++)
cout << *it << " ";
cout << endl;
}
void test2()
{
vector v;
v.push_back(10);
v.push_back(50);
v.push_back(60);
v.push_back(30);
v.push_back(10);
printVector(v);
//sort()排序
//1.普通函数,做谓词; 函数名
//sort(v.begin(), v.end(), greaterInt);
// 2.仿函数,做谓词;类名称+()
sort(v.begin(), v.end(), greaterInt2());
printVector(v);
}
int main() {
test2();
return 0;
}
//sort(v.begin(), v.end())//默认升序,如想要降序,就要增加排序规则
//前面自定义谓词函数(1.普通函数 2.仿函数),作为排序规则
//方法3 使用内置函数对象(仿函数);;;greater();;;大于<数据类型>()
//内建函数对象,排序
void test3()
{
vector v;
v.push_back(10);
v.push_back(50);
v.push_back(60);
v.push_back(30);
v.push_back(10);
printVector(v);
//sort()排序
//sort(v.begin(), v.end())//默认升序,如想要降序,就要增加排序规则
//前面自定义谓词函数(1.普通函数 2.仿函数),作为排序规则
//方法3 使用内置函数对象(仿函数);;;greater();;;大于<数据类型>()
sort(v.begin(), v.end(), greater());
printVector(v);
}
//内建函数对象,查找
void test4() {
vector v;
v.push_back(10);
v.push_back(50);
v.push_back(60);
v.push_back(30);
v.push_back(10);
find_it条件查找; 找到都一个> value的数,找到满足条件的元素,就返回迭代器
vector::iterator ret;
//1.普通函数,做谓词; 函数名
//ret = find_if(v.begin(),v.end(),greaterThan30);
// 2.仿函数,做谓词;类名称+()
//ret = find_if(v.begin(), v.end(), greaterThan30_());
//方法3 内建函数,查找
ret = find_if(v.begin(), v.end(),bind2nd(greater(), 30));//适配器bind2nd,头文件
//因find_if()只能接受三个参数,内建函数greater(), 30加进来就相当于4参数了,故用适配器将其绑定
if (ret != v.end())
cout << "找到元素为:" << *ret << endl;
else
cout << "元素未找到" << endl;
}
bind1st、 bind2nd头文件;
作用:将一个二元算子转换成一个一元算子;
bind1st是绑定第一个参数,bind2nd则是绑定第二个参数。
由于二元函数对象接受两个参数,在绑定成为一元函数对象时需要将原来两个参数中的一个绑定下来。
将二元函数的一个参数绑定为定值,这样二元函数就转换为了一元函数,传进来的参数都相当于是另外一个参数了。
bind就是绑定的意思,而1st就代表first,2nd就代表second;
他们的申明是一样的,都是(const Operation& op, const T& x);
bind1st(const Operation& op, const T& x)就是这么一个操作:x op value,
bind2nd(const Operation& op, const T& x)就是这么一个操作:value op x,
其中value是被应用bind的对象。
例:查找,大于10的元素个数;小于10的元素的个数
(less(), 10) VS (greater(), 10)
bind1st VS bind2nd
(less(), 10)
void test1() {
vector v;
for (int i = 1; i <= 10; ++i)
v.push_back(i);
//查找值大于10的元素的个数
//也就是使得10 < elem成立的元素个数
int res = count_if(v.begin(), v.end(), bind1st(less(), 10));// x op value,即 10 less elem,10 < elem,大于10的元素
cout <<"大于10的元素个数:" <(), 10));// value op x,即 elem less 10,elem < 10,小于10的元素
cout << "小于10的元素个数:" << res << endl;
}
bind1st(less(), 10);// x op value,即 10 less elem,10 < elem,大于10的元素
bind2nd(less(), 10);// value op x,即 elem less 10,elem < 10,小于10的元素
(greater(), 10)
void test2() {
vector v;
for (int i = 1; i <= 10; ++i)
v.push_back(i);
//查找值大于10的元素的个数
int res = count_if(v.begin(), v.end(), bind2nd(greater(), 10));// value op x,即 elem greator 10,elem > 10,大于10的元素
cout << "大于10的元素个数:" << res << endl;
//查找小于10的元素的个数
res = count_if(v.begin(), v.end(), bind1st(greater(), 10));// x op value,即 10 greater elem,10 > elem,小于10的元素
cout << "小于10的元素个数:" << res << endl;
}
bind2nd(greater(), 10));// value op x,即 elem greator 10,elem > 10,大于10的元素
bind1st(greater(), 10));// x op value,即 10 greater elem,10 > elem,小于10的元素
之前用迭代器遍历容器
void printVector(vector& v) {
vector::iterator it = v.begin();
for (; it != v.end(); it++)
cout << *it << " ";
cout << endl;
}
for_each()遍历容器
//定义方法
class printVectorInt {
public:
void operator()(int val) {
cout << val << " ";
}
};
//for_each()遍历容器
void test5() {
vector v;
v.push_back(10);
v.push_back(50);
v.push_back(60);
v.push_back(30);
v.push_back(10);
//注意for_each()里面是逗号,不是分号
for_each(v.begin(), v.end(), printVectorInt());
cout << endl;
}
比如+100 ;;cout << val + 100<< " ";
class printVectorInt {
public:
void operator()(int val) {
cout << val + 100<< " ";
}
};
但是这样是在仿函数里面修改,
我们希望函数写好后就不再修改,在调用的时候,修改调用入口参数;
//第二步:公共继承 binary_function 参数萃取
class printVectorInt:binary_function {
public:
//第三步:const修饰operator()
void operator()(int val, int temp) const{
//cout << val + temp << " ";
cout << "val = " <
bind1st是绑定第一个参数,bind2nd则是绑定第二个参数。
不知道为啥,我在VS2022上无法运行,
提示我的printVectorInt使用私有去继承公共继承 binary_function,,,,不懂
//普通函数名 作为适配器
void printVectorInt(int val, int temp){
cout << "val = " << val << " temp = " << temp << endl;
}
//for_each()遍历容器
void test4() {
vector v;
v.push_back(10);
v.push_back(50);
v.push_back(60);
v.push_back(30);
v.push_back(10);
//注意for_each()里面是逗号,不是分号
//第一步: bind2nd或bind1st绑定参数
for_each(v.begin(), v.end(), bind1st(ptr_fun(printVectorInt), 200));
cout << endl;
}
for_each(v.begin(), v.end(), bind2nd(ptr_fun(printVectorInt), 200));
//成员函数 作为适配器 mem_fun_ref
class Data {
public:
Data() {}
Data(int val) {
this->data = val;
}
void printVectorInt(int temp) {
cout << "val = " << data << " temp = " << temp << endl;
}
int data;
};
void test5() {
vector v;
v.push_back(Data(10));
v.push_back(Data(50));
v.push_back(Data(60));
v.push_back(Data(30));
v.push_back(Data(10));
//注意for_each()里面是逗号,不是分号
//第一步: bind2nd或bind1st绑定参数
for_each(v.begin(), v.end(), bind2nd(mem_fun_ref(&Data::printVectorInt), 200));
cout << endl;
}
//取反适配器
void test6() {
vector v;
v.push_back(10);
v.push_back(50);
v.push_back(60);
v.push_back(30);
v.push_back(10);
vector::iterator ret;
//bind2nd(greater(), 30),,查找 >30的第一个元素,,前面加not1后,变成查找 <=30的第一个元素
ret = find_if(v.begin(), v.end(), not1(bind2nd(greater(), 30)));
if(ret != v.end())
cout <<"找到相关数据:"<<*ret<< endl;
}
//not2 二元取反
void test7() {
vector v;
v.push_back(10);
v.push_back(50);
v.push_back(60);
v.push_back(30);
v.push_back(10);
//lambda 表达式 c++11才支持
//[]里面啥都不写 lambda不能识别 外部数据
//[=] lambda能对 外部数据 读操作
//[&] lambda能对 外部数据 读写操作
for_each(v.begin(), v.end(), [&](int val) {cout << val << " "; });
cout << endl;
//greater() 内建函数对象 降序策略,,not2取反后,变为升序排列
sort(v.begin(),v.end(),not2(greater()));
for_each(v.begin(), v.end(), [&](int val) {cout << val <<" "; });
cout << endl;
}
运行到sort的二园区反,就终止。为何?不知道