仿函数:
解释:让一个类在使用时像一个函数。
实现:在类中进行操作符重载()
约束:重载操作符()时,编写参数个数一定要跟调用时一致(for_each()函数中使用一个参数的仿函数,所以在编写class:show中重载()时 和 show_more_than()时只有一个参数)。
使用仿函数:通过类声明的对象(一般用临时对象),在创建对象时传参,参考下面代码块1
定义仿函数
#include <iostream>
#include <string>
using namespace std;
//定义仿函数
struct functor {
private:
const int maxLength;
public:
functor(const int max)
:maxLength(max) {}
// ()操作符重载
bool operator ()(const string& str)const {
return str.length() < maxLength;
}
};
int main() {
string str = "this is test safdasdfasdfasd string";
//方法1.声明动态变量对象
functor fun(20);
cout << fun(str) << endl;
//方法2.声明了临时变量对象
cout << functor(100)(str)<< endl;
return 0;
}
仿函数在STL中的应用
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using std::cout;
using std::endl;
using std::exception;
using std::vector;
using std::sort;
using std::for_each;
//根据实际情况定义vector中实际存储的类
class Ston {
public:
Ston(const double& we,const double& vo)
:weigth(we),volume(vo)
{
}
double weigth;
double volume;
double getWeigth() {
return weigth;
}
double getVolume() {
return volume;
}
};
//仿函数
template <class Type>
struct show {
void operator ()( Type& s1)const {
cout << s1.getWeigth()<< endl;
}
};
//
template <typename Type>
void show_more_than(Type& s1) {
if (s1.getWeigth() > 100.0)
cout << s1.getWeigth() << endl;
}
int main() {
vector<Ston> ston;
for (int i = 0; i < 10; i++) {
try {
ston.push_back(Ston(i*i,2*i*2*i));//这里插入元素
}
catch (exception& e) {
cout << e.what() << endl;
exit(0);
}
}
for (Ston i : ston) {
cout << "weigth = " << i.weigth << " volume= " << i.volume << endl;
}
cout << endl;
vector<Ston>::iterator iterator = ston.begin();
//在for_each()中使用仿函数
for_each(ston.begin(),ston.end(), show<Ston>());//com<Ston>()声明一个对象,可以看下一个代码块,在源码中怎么使用这个对象
cout << endl << "this is more than 100" << endl;
//在for_each()中使用函数show_more_than()
for_each(ston.begin(), ston.end(), show_more_than<Ston>);
return 0;
}
visual 2019中的源码:
/*
摘录自visual 2019 中的for_each() source code
参数:
_InIt _First //上一个代码快的第一个参数,是一个迭代器begin()
_InIt _Last //上一个代码块的第二个参数,是一个迭代器end()
_Fn _Func //上一个代码块的show<Ston>()
Func(*_UFirst); //这里是使用show<Ston>这个临时对象,for_each()将会把传给自己的第一个参数
作为show()的参数,first并不断自增(迭代器自增,指向下一个元素)
*/
template <class _InIt, class _Fn>
inline _Fn for_each(_InIt _First, _InIt _Last, _Fn _Func) { // perform function for each element [_First, _Last)
_Adl_verify_range(_First, _Last);
auto _UFirst = _Get_unwrapped(_First);
const auto _ULast = _Get_unwrapped(_Last);
for (; _UFirst != _ULast; ++_UFirst) {
_Func(*_UFirst);
}
return _Func;
}