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

免费网站建设软件网络seo软件

免费网站建设软件,网络seo软件,wordpress 更好的主题,湛江论坛网1. 什么是包装器 C中的包装器是一种设计模式,用于将一个复杂或底层的接口进行封装,以便提供一个更简洁、易用的接口。包装器可以包装任何类型的可调用实体,如函数,成员函数,函数指针,仿函数对象&#xff0…

1. 什么是包装器

C++中的包装器是一种设计模式,用于将一个复杂或底层的接口进行封装,以便提供一个更简洁、易用的接口。包装器可以包装任何类型的可调用实体,如函数,成员函数,函数指针,仿函数对象,lambda表达式等。

包装器在资源管理、接口封装、类型安全等方面有广泛应用。

在实际编程中,包装器可以用于回调机制、事件处理、异步编程等场景。它们提供了灵活的函数调用机制,使得代码更加模块化和可重用。

综上所述,C++包装器是提升代码可读性、可维护性和性能的有力工具。通过使用标准库(<functional>头文件)中提供的包装器类,开发者可以更方便地处理各种可调用对象。

2. function

在C++标准库中,std::function是一个模板类,它用作一个通用的函数包装器,能够存储、复制和调用任何可调用的目标。

template <class T>
class function; template <class Ret, class... Args>
class function<Ret(Args...)>;

2.1 包装非成员函数 

在对可调用对象进行包装的时候,需要在类型参数列表中指定可调用对象的返回值和参数列表:

#include<functional>
#include<iostream>
using namespace std;int f(int a, int b)
{return a + b;
}struct Functor
{ 
public:int operator() (int a, int b){return a + b;}
};int main()
{// 包装各种可调用对象function<int(int, int)> f1 = f;function<int(int, int)> f2 = Functor();function<int(int, int)> f3 = [](int a, int b) {return a + b; };cout << f1(1, 1) << endl;cout << f2(1, 1) << endl;cout << f3(1, 1) << endl;return 0;
}

可以认为是编译器对包装器做的特殊处理吧。

 2.2 成员函数

与普通函数不同的是,不能直接使用成员函数的函数名来进行包装,必须对其进行取地址(&)。

注意:(1) 访问成员函数要指定类域;(2) 普通成员函数的参数列表中有隐含的this指针。

#include<functional>
#include<iostream>
using namespace std;class Plus
{
public:Plus(int n = 10): _n(n){}static int plusi(int a, int b){return a + b;} double plusd(double a, double b){return (a + b) * _n;}
private:int _n;
};int main()
{// 包装静态成员函数// 成员函数要指定类域并且前面加&才能获取地址function<int(int, int)> f4 = &Plus::plusi;cout << f4(1, 1) << endl;// 包装普通成员函数// 普通成员函数还有⼀个隐含的this指针参数,所以绑定时传对象或者对象的指针过去都可以function<double(Plus*, double, double)> f5 = &Plus::plusd;Plus pd;cout << f5(&pd, 1.1, 1.1) << endl;function<double(Plus, double, double)> f6 = &Plus::plusd;cout << f6(pd, 1.1, 1.1) << endl;cout << f6(pd, 1.1, 1.1) << endl;function<double(Plus&&, double, double)> f7 = &Plus::plusd;cout << f7(move(pd), 1.1, 1.1) << endl;cout << f7(Plus(), 1.1, 1.1) << endl;return 0;
}

2.3 逆波兰表达式求值. - 力扣(LeetCode)

在学习function之前,我们可以使用switch语句来建立运算符与运算逻辑之间的关系:

// 传统方式的实现
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();}
};

在学习function之后,我们可以使用map来建立二者的关系:

// 使用map映射string和function的方式实现
// 这种方式的最大优势之一是方便扩展,假设还有其他运算,我们增加map中的映射即可
class Solution {
public:int evalRPN(vector<string>& tokens) {stack<int> st;// function作为map的映射可调用对象的类型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)) // 操作符{int right = st.top();st.pop();int left = st.top();st.pop();int ret = opFuncMap[str](left, right);st.push(ret);} else{st.push(stoi(str));}} return st.top();}
};

 之前无法使用这样的方式来做的原因是:各个lambda表达式(或其他可调用对象)的类型不一样,导致这些lambda表达式无法放到同一个map中进行管理。

可以说,function包装器的一大作用就是可以将返回值和参数列表相同的一类可调用对象的类型统一起来,方便传参或存储。

3. bind

std::bind也是C++标准库中的一个包装器,它的主要作用是将一个可调用对象的参数进行调整,生成并返回一个新的可调用对象。

// 不显示指定返回类型,编译器自动推导
template <class Fn, class... Args>
typename std::result_of<Fn(Args...)>::type bind(Fn&& fn, Args&&... args);// 显式指定返回类型
template <class Ret, class Fn, class... Args>
Ret bind(Fn&& fn, Args&&... args);

std::bind的主要作用有两个:

(1)指定某个参数的值并绑定到新的可调用对象。

(2)调整参数的顺序。

Args是一个占位符列表,用于在绑定时指定传递给可调用对象的参数。

这些占位符可以是实际的参数值,也可以是std::placeholders命名空间中定义的占位符,如std::placeholders::_1std::placeholders::_2等,它们在后续的调用中会被实际传递的参数所替代。

3.1 调整参数顺序

 利用std::placeholders命名空间中定义的占位符,我们可以对参数的顺序进行调整。

_1、_2、...、_n分别代表原函数中的第1个参数、第2个参数、...、第n个参数。

在bind的参数列表中按我们需要的顺序给出这些占位符,就可以实现参数顺序的调整:

#include<functional>
#include<iostream>
using namespace std;
using placeholders::_1;
using placeholders::_2;
using placeholders::_3;int Sub(int a, int b)
{return (a - b) * 10;
}int main()
{// bind 本质返回的一个仿函数对象// 调整参数顺序(不常用)// _1代表第一个实参// _2代表第二个实参// ...// 10->_1(对应a), 5->_2(对应b), 结果为50auto sub1 = bind(Sub, _1, _2);cout << sub1(10, 5) << endl;// 10->_2(对应b), 5->_1(对应a), 结果为-50auto sub2 = bind(Sub, _2, _1);cout << sub2(10, 5) << endl;return 0;
}

3.2 绑定参数

当占位符是实际的参数值时,对应位置的参数的值会被绑定为该实际值:

#include<functional>
#include<iostream>
using namespace std;
using placeholders::_1;
using placeholders::_2;
using placeholders::_3;int Sub(int a, int b)
{return (a - b) * 10;
}int SubX(int a, int b, int c)
{return (a - b - c) * 10;
}class Plus
{ 
public:static int plusi(int a, int b){return a + b;} double plusd(double a, double b){return a + b;}
};int main()
{// 调整参数个数auto sub3 = bind(Sub, 100, _1);cout << sub3(5) << endl;auto sub4 = bind(Sub, _1, 100);cout << sub4(5) << endl;// 分别绑死第123个参数auto sub5 = bind(SubX, 100, _1, _2);cout << sub5(5, 1) << endl;auto sub6 = bind(SubX, _1, 100, _2);cout << sub6(5, 1) << endl;auto sub7 = bind(SubX, _1, _2, 100);cout << sub7(5, 1) << endl;// 成员函数对象进行绑定,就不需要每次都传递了function<double(Plus&&, double, double)> f6 = &Plus::plusd;Plus pd;cout << f6(move(pd), 1.1, 1.1) << endl;cout << f6(Plus(), 1.1, 1.1) << endl;// bind一般用于绑定一些固定参数function<double(double, double)> f7 = bind(&Plus::plusd, Plus(), _1, _2);cout << f7(1.1, 1.1) << endl;// 计算复利的lambdaauto func1 = [](double rate, double money, int year)->double {double ret = money;for (int i = 0; i < year; i++){ret += ret * rate;} return ret - money;};// 绑定一些参数,实现出支持不同年华利率,不同⾦额和不同年份计算出复利的结算利息function<double(double)> func3_1_5 = bind(func1, 0.015, _1, 3);function<double(double)> func5_1_5 = bind(func1, 0.015, _1, 5);function<double(double)> func10_2_5 = bind(func1, 0.025, _1, 10);function<double(double)> func20_3_5 = bind(func1, 0.035, _1, 30);cout << func3_1_5(1000000) << endl;cout << func5_1_5(1000000) << endl;cout << func10_2_5(1000000) << endl;cout << func20_3_5(1000000) << endl;return 0;
}

注意:某参数被绑定之后,占位符的对应关系中不再考虑该参数,而是对剩下的参数依次编号为_1、_2、...、_n-1,多个参数被绑定时同理。

http://www.tj-hxxt.cn/news/35946.html

相关文章:

  • 聊城做网站公司百度指数购买
  • 电子商务网站体系结构有哪些北京网站优化对策
  • 嘉兴网站seo公司seo标题优化
  • 青岛网站建设找润商站外推广渠道
  • 手机网站怎么建网站域名查询
  • 合肥建设工程信息网seo诊断优化专家
  • 南昌做网站公司哪家好营销技巧有哪些
  • 做暧暖ox免费视频网站网店seo是什么意思
  • b2b性质网站怎么进行推广个人开发app可以上架吗
  • 沈阳做网站最好的公司有哪些西seo优化排名
  • 网站建设资金管理办法百度合作平台
  • python php 做网站找培训机构的网站
  • 网站建设的目前背景网站优化和网站推广
  • 西安好的网站建设公司小红书seo排名优化
  • 怎么样找到做直销的人 有什么网站seo优化网站模板
  • 安徽网站建站系统哪家好2022搜索引擎
  • 外贸网站运营推广百度快照入口官网
  • 服务器和网站的关系黑帽seo技巧
  • 零基础免费学编程app抖音seo推广
  • 网站域名的组成公关公司一般收费标准
  • 北京一个公司做网站认证百度广告联盟网站
  • 龙岗平湖网站建设公司关键词排名优化营销推广
  • 卡片式设计的网站全网网络营销推广
  • 创意平面设计公司公司排名沧州seo公司
  • 制作网站复杂吗长沙企业网站建设报价
  • 有没有专做食品批发的网站杭州seo公司
  • 广州一起做网店网站东莞营销网站建设优化
  • wordpress邮件样式美化厦门seo哪家强
  • 淘宝网站开发费用站长统计app软件下载2021
  • 网站建设 关于我们网站联盟广告