0.含义
仿函数和函数对象在C++中含义一致。官方解释是:
()就是函数调用运算符,也就是说一个类重载了小括号,它实例化的对象就可以像函数一样使用。
“仿”函数,意味着它和函数使用有相同点:
单看红框,你可能会认为我调用了int add(int a,int b);这个函数。
1.基本使用
如上图,我们可以起先构建一个对象,然后使用对象加括号的方式来使用。
也可以类名+括号的方式构建一个匿名对象,然后紧跟小括号来使用。即Adder<int>是一个具体的类型,类型加上括号就是构建对象,只不过是个匿名的对象,对象假设叫做obj,obj(89,11);因为我们重载了小括号,这句话相当于obj.operator()(89,11);调用了Adder的成员函数。
但是第二种方法在637这里过不了,因为&限制只有左值可以调用,但是你匿名对象明显是右值。
同理,你使用&&,那么643就过不了。
2.基本使用
仿函数常常与算法搭配起来使用,如上,我们将匿名对象传递给my_for_each函数,遍历到某个值时,该对象调用重载的小括号函数,并将值送进去打印出来。
3.库提供了内置的仿函数
有了Lambda表达式后,我们也可以:
那么Lambda表达式完全替代了仿函数吗?没有
如上我们知道map默认是按照key从小到大排序的,我们可以改变它为从大到小。此时,<>中需要一个类型,但是你Lambda表达式无法胜任。即:<>中你Lambda表达式无法胜任,但是()中你可以大展拳脚。比如list的sort。
4.源码
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<list>
using namespace std;
#include <iostream>
#include <vector>
#include <algorithm>class Adder {
private:int value;
public:Adder(int v) : value(v) {}int operator()(int x) const {return x + value;}
};int main() {std::vector<int> values = { 1, 2, 3, 4, 5 };Adder adder(10);//应用仿函数于std::transform中std::vector<int> results;std::transform(values.begin(), values.end(), std::back_inserter(results), adder);for (int result : results) {std::cout << result << " ";}return 0;
}#if 0
int main() {list<int> lt{ 1,5,9,5,1,5 };lt.sort(greater<int>());//9 5 5 5 1 1
}int main() {vector<int> vec{ 99,1,2,3,4,5,6 };sort(vec.begin(), vec.end(), [](const int& a, const int& b)->bool {return a > b;});//99 6 5 4 3 2 1
}
int main() {std::plus f;cout << f(45, 55) << endl;std::string s{ "hello" };const char* p = "world";auto string_plus = std::plus<void>();cout << string_plus(p, s) << endl;
}template<class _II,class _Fn>
void my_for_each(_II _F,_II _L,_Fn fn) {for (; _F != _L; _F++) {fn(*_F);}
};
template<class T>
struct Print {void operator()(const T& val) const{cout << val << " ";}
};
int main() {vector<int> vec{ 45,484,561,8984,896 };my_for_each(vec.begin(), vec.end(), Print<int>());return 0;
}template<class T>
struct Adder {const T& operator()(const T& a,const T& b) const {return a + b;}
};
int main() {Adder<int> add;int c = add(14, 86); cout << c << endl;c = Adder<int>()(89, 11);cout << c << endl;
}#endif