本文为《C++ Primer》的读书笔记
bind
创建的对象以及重载了函数调用运算符的类int(int, int)
// 普通函数
int add(int i, int j) {
return i + j; }
// lambda, 其产生一个未命名的函数对象类
auto mod = [](int i, int j) {
return i % j; };
// 函数对象类
struct divide {
int operator() (int denominator, int divisor) {
return denorninator / divisor;
};
};
int (int, int)
map
来实现。对于此例来说, 我们使用一个表示运算符符号的 string
对象作为关键字;使用实现运算符的函数作为值int
的二元运算, 则 map
可以定义成如下的形式:// 构建从运算符到函数指针的映射关系, 其中函数接受两个 int、返回一个 int
map<string, int(*) (int, int)> binops;
// 将 `add` 的指针添加到 `binops` 中
binops.insert({
"+", add});
mod
或者divide
存入binops
。问题在于mod
是个 lambda 表达式, 而每个 lambda 有它自己的类类型, 该类型与存储在 binops
中的值的类型不匹配function
模板类#include
function
类型表示接受两个int
、返回一个int
的可调用对象。甚至只要可调用对象的参数和返回类型能够隐式转化为 int
即可function<int(int, int)>
function<int (int, int)> f1 = add; // 函数指针
function<int (int, int)> f2 = divide(); // 函数对象类的对象
function<int (int, int)> f3 = [] (int i, int j) // lambda
{
return i * j; };
cout << f1(4,2) << endl;
cout << f2(4,2) << endl;
cout << f3(4,2) << endl;
function
类型我们可以重新定义 map
:map<string, function<int(int, int)>> binops = {
{
"+", add}, // 函数指针
{
"-", std::minus<int>()}, // 标准库函数对象
{
"I", divide()}, // 用户定义的函数对象
{
"*", [](int i, int j) {
return i * j; }}, // 未命名的lambda
{
"%", mod}}; // 命名了的 lambda 对象
};
binops["+"](10, 5); //调用 add(10, 5)
binops["-"](10, 5); //使用 minus 对象的调用运算符
binops["/"](10, 5); //使用 divide 对象的调用运算符
binops["*"](10, 5); //调用 lambda 函数对象
binops["%"](10, 5); //调用 lambda 函数对象
int a, b;
string op;
cin >> a >> op >> b;
cout << binops[op](a, b) << endl;
function
function
类型的对象中:int add(int i, int j) {
return i + j; }
Sales_data add(const Sales_data&, const Sales_data&);
map<string, function<int(int, int)>> binops;
binops.insert( {
"+", add} ); //错误: 哪个add?
int (*fp)(int, int) = add; // 指针所指的 add 是接受两个int 的版本
binops.insert({
"+", fp}); // 正确: fp 指向一个正确的 add 版本
// 正确:使用lambda 未指定我们希望使用的add版本
binops.insert({
"+", [] (int a, int b) {
return add(a, b);} });