using namespace std;/*
//普通函数
int add(int i,int j){ return i+j; }
//lambda,其产生一个未命名的函数对象类.
auto mod = [](const int &i,const int &j){ return i+j; }
//函数对象类.
struct divide{
int operator()(int denominator,int divisor)
{
return denominator / divisor;
}
};
上面这些可调用对象,虽然类型不同,但是共享同一种调用形式:
int(int,int)
可以定义一个函数表,用于存储指向这些可调用对象的"指针".当程序需要执行某个特定的操作时,
从表中查找该调用的函数.
在C++中,函数表很容易通过map来实现.
*/
int add(int i,int j){
return i+j;
}
struct divide{
int operator()(int denominator,int divisor)
{
return denominator / divisor;
}
};
int main()
{
auto mod = [](const int &i,const int &j){ return i+j; };
map binops;
binops.insert({"+",add});
//但是我们不能将mod或者divide存入binops.因为mod不是一个函数指针.
//问题在于mod是个lambda表达式,而每个lambda有它自己的类类型,该类型与存储在binops中的值得类型不匹配.
//解决办法如下:
//使用一个名为function的新的标准库类型解决上述问题.
/*function f1 = add;//函数指针
function f2 = divide();//函数对象类的对象.
function f3 = [](int i,int j){ return i * j ; }; //lambda
cout << f1(4,2) << endl;
cout << f2(4,2) << endl;
cout << f3(4,2) << endl;*/
//使用function类型我们可以重新定义map.
map> binops2={
{"+",add}, //函数指针.
{"-",std::minus()}, //标准库函数对象
{"/",divide()}, //用户定义的函数对象.
{"*",[](int i,int j){ return i * j ;}}, //未命名的lambda
{"%",mod} //命名了的lambda对象
};
cout << "10+5=" << binops2["+"](10,5) << endl;//调用add(10,5)
cout << "10-5=" << binops2["-"](10,5) << endl;//调用minus
cout << "10/5=" << binops2["/"](10,5) << endl;//调用divide
cout << "10*5=" << binops2["*"](10,5) << endl;//调用lambda
cout << "10%5=" << binops2["%"](10,5) << endl;//调用lambda
/*
我们不能(直接)将重载函数的名字存入function类型的对象中:
int add(int i,int j){return i+j;}
Sales_data add(const Sales_data&,const Sales_data&);
map> binops3;
binops3.insert({"+",add}); //错误:哪个add?
解决上述二义性的问题是存储函数指针而非函数的名字:
int (*fp)(int,int) =add; //指针所指的add是接受两个int的版本.
binops3.insert({"+",fp}); //正确:fp指向一个正确的add版本
同样,也可以用lambda来消除二义性:
//正确:使用lambda来指定我们希望使用的add版本
binops3.insert({"+",[](int a,int b){return add(a,b);}});
*/
return 0;
}