当前位置: 首页 > news >正文

网站建设的研发支出费用化建筑公司企业信用分

网站建设的研发支出费用化,建筑公司企业信用分,牡丹江百姓网免费发布信息,wordpress页面 文章页 分类文章目录 1. function包装器1.1 遇到的问题1.2 包装器的定义1.3 解决问题1.4 包装器的其他应用 2. bind2.1 bind的定义2.2 bind包装器绑定固定参数2.3 bind包装器调整传参顺序2.4 bind包装器的意义 1. function包装器 1.1 遇到的问题 我们首先来看一行代码: ret …

文章目录

  • 1. function包装器
    • 1.1 遇到的问题
    • 1.2 包装器的定义
    • 1.3 解决问题
    • 1.4 包装器的其他应用
  • 2. bind
    • 2.1 bind的定义
    • 2.2 bind包装器绑定固定参数
    • 2.3 bind包装器调整传参顺序
    • 2.4 bind包装器的意义

1. function包装器

1.1 遇到的问题

我们首先来看一行代码:

ret = func(x);

假设这行代码能够正常运行,那么这个func是什么呢?函数名? 函数指针? 函数对象? lambda表达式对象?很多种可能性,这些都是可调用的类型。这么多的类型可能会导致模板的效率低下

template<class F, class T>
T useF(F f, T x)
{static int count = 0;cout << "count:" << ++count << endl;cout << "&count:" << &count << endl;return f(x);
}
double f(double i)
{return i / 2;
}
struct Functor
{double operator()(double d){return d / 3;}
};
void Test1()
{cout << useF(f, 11.11) << endl;//函数名cout << useF(Functor(), 11.11) << endl;//函数对象cout << useF([](double d)->double {return d / 4; }, 11.11) << endl;//lambda表达式
}

image-20230727094927877

可以看到这里的useF函数模板被实例化了三份。但是使用function包装器就可以让只被实例化一份出来。


1.2 包装器的定义

function包装器,也叫做适配器。C++中的function本质是一个类模板

image-20230727092701982

模板参数说明:

  • Ret:被包装的可调用对象的返回值类型
  • Args…:可调用对象的参数包

如何使用包装器呢?

int func(int a, int b)
{return a + b;
}
struct Functor
{
public:int operator() (int a, int b){return a + b;}
};
class Plus
{
public:static int plusi(int a, int b){return a + b;}int plusd(int a, int b){return a + b;}
};
void Test2()
{//函数名(函数指针)function<int(int, int)> func1 = func;cout << func1(1, 2) << endl;//函数对象(仿函数)function<int(int, int)> func2 = Functor();cout << func2(1, 2) << endl;//lambda表达式function<int(int, int)> func3 = [](const int a, const int b)->int {return a + b; };cout << func3(1, 2) << endl;//类的静态成员函数function<int(int, int)> func4 = &Plus::plusi;//这里可以不加取地址符号cout << func4(1, 2) << endl;//类的成员函数function<int(Plus, int, int)> func5 = &Plus::plusd;//这里必须要加取地址符号,并且声明的时候需要显示的传类名cout << func5(Plus(), 1, 2) << endl;//调用的时候需要传对象
}

image-20230727101249743

1.3 解决问题

现在我们知道了包装器的用法了,那么怎么解决最开始的问题呢?

使用包装器包装可调用对象,然后将可调用对象传给useF

void Test3()
{function<double(double)> func1 = f;function<double(double)> func2 = Functor1();function<double(double)> func3 = [](double d)->double {return d / 4; };cout << useF(func1, 11.11) << endl;cout << useF(func2, 11.11) << endl;cout << useF(func3, 11.11) << endl;
}

image-20230727103219920

可以看到,这里的useF函数模板只实例化出了一个对象。

1.4 包装器的其他应用

我们之前做过一道题:逆波兰表达式求解150. 逆波兰表达式求值 - 力扣(LeetCode),当时使用的方法代码如下

class Solution {
public:int evalRPN(vector<string>& tokens) {stack<int> st;for(auto& str : tokens){if(str == "+" || str == "-" || str == "*" || str == "/"){int right = st.top();st.pop();int left = st.top();st.pop();switch(str[0]){case '+':st.push(left + right);break;case '-':st.push(left - right);break;case '*':st.push(left * right);break;case '/':st.push(left / right);break;}}else//遇到数字{st.push(stoi(str));}}return st.top();}
};

在这里我们使用switch语句来判断运算类型,还需要在前面的条件里面枚举出运算类型,非常麻烦,如果在工程中,这段代码的可维护性就非常差,需要在if语句中增加枚举,在switch语句中增加case语句,这种情况就可以使用包装器来简化代码

  • 首先建立运算符和执行函数之间的映射关系,当需要某一运算的时候就直接通过运算符找到对应的可调用对象调用即可。、
  • 当运算类型增加时,只需要增加运算符和执行函数之间的映射关系即可

那么修改后的代码如下

class Solution {
public:int evalRPN(vector<string>& tokens) {stack<int> st;map<string, function<int(int, int)>> opFuncMap = {{"+", [](int x, int y){return x + y;}},{"-", [](int x, int y){return x - y;}},{"*", [](int x, int y){return x * y;}},{"/", [](int x, int y){return x / y;}}};for(auto& str : tokens){if(opFuncMap.count(str) == 0){st.push(stoi(str));}else{int right = st.top();st.pop();int left = st.top();st.pop();st.push(opFuncMap[str](left, right));}}return st.top();}
};

2. bind

2.1 bind的定义

**bind时一个函数模板,就像是一个函数包装器(适配器),接受一个可调用对象,生成一个新的可调用对象来”适应“原对象的参数列表。**一般而言,我们用它可以把一个原本接收N个参数的函数fn,通过绑定一些参数,返回一个接收M个(M可以大于N,但这么做没什么意义)参数的新函数。同时,使用bind函数还可以实现参数顺序调整等操作。

image-20230727140931890

参数列表说明:

  • Fn:可调用对象
  • Ret:可调用对象的返回类型
  • Args:要绑定的参数列表:值或者时占位符

可以将bind函数看作是一个通用的函数适配器,它接受一个可调用对象,生成一个新的可调用对象来“适应”原对象的参数列表。调用bind的一般形式:auto newCallable = bind(callable,arg_list)

  • newCallable:生成的新的可调用对象

  • callable:需要包装的可调用对象

  • arg_list:逗号分隔的参数列表,对应给定的callable的参数,当调用newCallable的时候,newCallable会调用callable,并传给他arg_list中的参数。

一般使用bind调整参数位置的时候,会使用一个类placeholders,这是一个占位符类。

image-20230727142425111

表示newCallable的参数,它们占据了传递给newCallable的参数的“位置”。数值n表示生成的可调用对象中参数的位置,比如_1为newCallable的第一个参数,_2为第二个参数,以此类推。

此外,除了用auto接收包装后的可调用对象,也可以用function类型指明返回值和形参类型后接收包装后的可调用对象。

2.2 bind包装器绑定固定参数

首先我们来看一种无意义的绑定

int Sub(int a, int b)
{return a - b;
}
void Test4()
{function<int(int, int)> func1 = bind(Sub, placeholders::_1, placeholders::_2);cout << func1(1, 3) << " " << Sub(1, 3) << endl;
}

绑定时第一个参数传入函数指针这个可调用对象,但后续传入的要绑定的参数列表依次是placeholders::_1和placeholders::_2,表示后续调用新生成的可调用对象时,传入的第一个参数传给placeholders::_1,传入的第二个参数传给placeholders::_2。此时绑定后生成的新的可调用对象的传参方式,和原来没有绑定的可调用对象是一样的,所以说这是一个无意义的绑定。

如果想让Sub的第二个参数固定绑定为10,就可以将绑定时的参数列表的palceholder::_2设置为10.

int Sub(int a, int b)
{return a - b;
}
void Test4()
{function<int(int)> func2 = bind(Sub, placeholders::_1, 10);cout << func2(2) << endl;
}

此时调用绑定后新生成的可调用对象时就只需要传入一个参数,它会将该值减10后的结果进行返回。

2.3 bind包装器调整传参顺序

同样的对于上面的Sub函数的例子,我们想让传入的参数顺序进行调换,也可以使用bind实现。将placeholder::_1和placeholder::_2的位置进行调换即可

void Test5()
{function<int(int, int)> func = bind(Sub, placeholders::_2, placeholders::_1);cout << func(1, 2) << endl;
}

根本原因就是因为,后续调用新生成的可调用对象时,传入的第一个参数会传给placeholders::_1,传入的第二个参数会传给placeholders::_2,因此可以在绑定时通过控制placeholders::_n的位置,来控制第n个参数的传递位置。

2.4 bind包装器的意义

  • 将一个函数的某些参数绑定为固定的值,让我们在调用时可以不用传递某些参数。
  • 可以对函数参数的顺序进行灵活调整。

本节完…

http://www.yayakq.cn/news/781491/

相关文章:

  • 怎么看网站有没有被收录竞价推广返点开户
  • idc销售网站php源码网银在线北京网络科技有限公司
  • 电子网站建设方案做网站用的文本编辑器
  • jsp和servlet网站开发html代码是什么意思
  • 青岛黄岛网站建设软件开发net教程免费
  • 一个公司做两个网站的多吗wordpress粒子插件
  • 营销策划 网站凡科精选app
  • 网站设计的步骤南昌专业做网站公司
  • 小馋网站建设书dw做网站后台
  • 哈尔滨市香坊区建设局网站杭州微网站建设公司
  • 网站视频解析互联网传媒公司
  • 台州路桥做网站的公司黑龙江省建设安全教育信息网
  • logo参考网站东营网络推广
  • 做阿里巴巴跟网站哪个更好网站建设与维护的试卷
  • 怎样在国外网站购买新鲜橙花做纯露怎么制作网页版的新闻
  • 如何自己做网站发布到服务器上面微信5000人接推广费用
  • qq网页版登陆上海优化公司排行榜
  • 综合网站系统网站维护和建设实报告
  • 中国建设招标网站抽奖页面设计
  • 网站开发汇报ppt模板外国男男做暧暧视频网站
  • 建设网站运营做一个私人网站需要多少钱
  • ps做网站需注意什么seo点击工具帮你火21星热情
  • 自助做app的网站旅游网网站建设
  • 建设好的网站怎么分享安卓app用什么开发
  • 网站站外推广方式有哪些网站美工培训机构
  • 怎么制作网站设计图片肯德基网站建设的目标
  • 礼盒包装设计网站高性能网站建设进阶
  • 网站管理助手4.1工作室设计
  • 网站上一页下一页怎么做大学 建网站
  • 重庆微信网站开如何用微信建设网站卖东西