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

没有做icp备案的网站五合一网站建设

没有做icp备案的网站,五合一网站建设,石家庄万达网站制作,免费微网站制作/ 文章目录 模版C作为静态类型语言宏可以摆脱数据类型的限制利用宏构建通用函数框架 函数模版函数模版的定义函数模版的使用函数模版的分析实例化函数模版的条件 函数模版扩展二次编译隐式推断类型实参函数模版的重载 bilibili 学习网址:https://www.bilibili.com/…

/

文章目录

  • 模版
    • C++作为静态类型语言
    • 宏可以摆脱数据类型的限制
    • 利用宏构建通用函数框架
  • 函数模版
    • 函数模版的定义
    • 函数模版的使用
    • 函数模版的分析
    • 实例化函数模版的条件
  • 函数模版扩展
    • 二次编译
    • 隐式推断类型实参
    • 函数模版的重载

bilibili 学习网址:https://www.bilibili.com/video/BV1NN4y1F7aY?spm_id_from=333.788.videopod.episodes&vd_source=0fc2f5466dc167b62ed0e5b774c4ab58

模版

C++作为静态类型语言

C++具有很多的数据类型(基本类型,类类型),在效率和类型安全上是无可比拟的。

但这种语言在很大程度上限制了程序员编写通用代码。

程序员不得不为每一种数据类型编写完全相同或近乎完全相同的代码实现,虽然他们在抽象层面是一致的。

#include <iostream>using namespace std;int max_int(int x, int y) {return x > y ? x : y;
}double max_double(double x, double y) {return x > y ? x : y;
}string max_string(string x, string y) {return x > y ? x : y;
}

宏可以摆脱数据类型的限制

宏是在预处理阶段针对代码的纯文本替换。

宏本身没有函数的语义(不会对数据类型进行检查)。

虽然可以摆脱类型的约束和限制,但同时也丧失了对数据类型的检查。

# include <iostream>using namespace std;#define Max(x, y) (x>y?x:y)int main() {int nx = 10, ny = 20;double dx = 12.3, dy = 45.6;string sx = "hello", sy = "world";//      会被替换成(nx>ny?nx:ny)cout << Max(nx, ny) << endl;cout << Max(dx, dy) << endl;cout << Max(sx, sy) << endl;// char cx[256] = "world", cy[256] = "hello";//         (cx>cy?cx:cy) 但这只比较了指针的大小,而没有比较字符串// cout << Max(cx, cy) << endl;
}

利用宏构建通用函数框架

通过实例化宏,让预编译器在编译过程中生成相应的函数。

但是代码可读性差。

# include <iostream>using namespace std;// 定义宏函数
#define Max(T) T max_##T(T x, T y) {\return x > y ? x : y; \
}// 实例化宏
Max(int)
// int max_int(int x, int y) { return x > y ? x : y; }Max(double)
// double max_double(double x, double y) {....}Max(string)
// string max_string(string x, string y) {....}// 解决代码可读性
# define Max(T) max_##T
int main() {int nx = 10, ny = 20;// cout << max_int(nx,ny) << endl;cout << Max(int)(nx,ny) << endl;double dx = 12.3, dy = 45.6;// cout << max_double(dx,dy) << endl;cout << Max(double)(dx,dy) << endl;string sx = "world", sy = "hello";cout << Max(string)(sx,sy) << endl;// cout << max_string(sx,sy) << endl;// 类型安全由程序员编写char cx[256] = "world", cy[256] = "hello";cout << Max(string)(cx,cy) << endl;return 0;
}

函数模版

函数模版的定义

  • 函数模版的定义形式:

    template<class 类型形参1, class 类型形参2, ...>
    返回值类型 函数模版名(调用形参1, 调用形参2, ...) {.... // 代码段
    }template<class T>T Max(T x, T y) {return x > y ? x : y;
    }
    

类型形参接受的是类型,调用形参接受的是数据。可以使用任何标识符作为类型形参的名称,但使用“T”已经成为了一种惯例。“T”表示调用者在使用这个函数模版时指定的任意数据类型。

函数模版的使用

使用函数模版必须对函数模版进行实例化。以下是实例化形式:

# include <iostream>using namespace std;template<class T>T Max(T x, T y) {return x > y ? x : y;
}
// 函数模版名<类型实参1, 类型实参2, ...>(调用形参1, 调用实参2, ...)
int main() {int nx = 10, ny = 20;cout << Max<int>(nx,ny) << endl;double dx = 12.3, dy = 45.6;cout << Max<double>(dx,dy) << endl;string sx = "hello", sy = "world";cout << Max<string>(sx,sy) << endl;
}

函数模版的分析

  • 编译器并不是把函数模版编译成一个可以处理任何数据类型的单一实体

  • 编译器在实例化函数模版时根据类型实参从函数模版中产生一个真正的函数实体

  • 函数模版并不是一个函数实体,通过实例化才能产生真正的函数实体

  • 函数模版可以看成是编译器生成函数实体的一个依据而已

  • 这种用具体数据类型替换函数模版类型形参的过程叫做实例化,这个过程将产生一个函数模版的实例(函数实体)

  • 只要使用函数模板,就会自动引发编译器的实例化过程,因此程序员不需要额外地请求对函数模版的实例化

实例化函数模版的条件

  • 原则上来说可以使用任何类型来实例化函数模版,不管其为数据类型还是类类型

  • 前提是这个类型必须支持函数模版所要执行的操作。

例如:一个不支持“>”操作符的类型来实例化Max函数模版,编译器将报错。

# include <iostream>using namespace std;class Interger{
public:Interger(int i)m_i(i){}// 重载Interger类型里面的操作符>bool operator>(Interger const& that)const{return m_i>that.m_i;}
private:int m_i;
};template<class T>T Max(T x, T y) {return x > y ? x : y;
}int main() {Interger ix = 100, iy = 200;// 在没有重载操作符">"之前,编译是会报错的cout << Max<Interger>(ix,iy) << endl;
}

函数模版扩展

二次编译

编译器对函数模版都会进行两次编译

  • 第一次编译发生在实例化函数模版之前(产生真正函数实体之前),只检查函数模版本身内部代码,查看基本词法是否正确。

    1. 函数模版内部出现的所有标识符是否均有声明

    2. 已知类型的调用要查看调用是否有效

    3. 对于未知类型调用认为都合理

    # include <iostream>using namespace std;class A {
    public:void func(){cout << "A:func()" << endl;}
    };template<class T>T foo() {// 标识符未声明,编译不通过fsfasfasjnf;// 已知类型调用查看调用是否有效A a;a.func();// cal()未声明,调用无效a.cal();// 未知类型的调用都认为合理T t;// 合理调用t.fisjadj();
    }int main() {return 0;
    }
    
  • 第二次编译发生在实例化函数模版之后(产生真正函数实体之后)结合所使用的类型实参,再次检查模版代码,查看所有调用是否真的均有效。

  • 第一次编译报错,谈不上第二次编译。

# include <iostream>using namespace std;class A {
public:void func(){cout << "A:func()" << endl;}
};template<class T>T foo() {// 标识符未声明,编译不通过fsfasfasjnf;// 已知类型调用查看调用是否有效A a;a.func();// cal()未声明,调用无效a.cal();// 未知类型的调用都认为合理T t;// 合理调用t.fisjadj();
}int main() {// 会报错,因为A里面没有声明fisjadj()函数foo<A>();return 0;
}

隐式推断类型实参

  • 如果函数模版的调用形参和类型形参相关。

例如:template<class T>T Max(T x, T y){...}

  • 那么在实例化函数模版时即时不显示指明函数模版的类型实参,编译器也有能力根据调用实参的类型隐式推断出正确的类型实参的类型。

例如:Max(123,456)→Max<int>(123,456)

函数模版的重载

待续…

http://www.dtcms.com/wzjs/348855.html

相关文章:

  • 专做正品 网站百度推广账号怎么注册
  • php+mysql网站开发全程实例 下载嘉兴seo外包公司
  • 专门做爬虫的网站不错宁波seo公司
  • 外卖小程序源码百度关键词优化排名技巧
  • 网站建设及第三方支付百度seo运营工作内容
  • 网站建设电话销售工作总结徐州seo排名收费
  • 互联网营销 网站 推荐万网官网域名查询
  • 网站服务器空间不足免费网站统计
  • 提高政府网站建设水平做网站多少钱一年
  • 网站制作案例如何自己弄个免费网站
  • 济南网站建设公拼多多关键词排名查询工具
  • 网站建设状况aso关键词优化工具
  • 自己做网站靠挂百度百度平台客服人工电话
  • html免费网站模板公司网站域名续费一年多少钱
  • 网站运营与管理的目的是谷歌商店下载安装
  • 网站建设行业 前景品牌推广策略
  • wordpress 更改zh_CN.po厦门谷歌seo公司有哪些
  • 深圳专门做兼职的网站查关键词排名工具app
  • 乐从网站建设公司如何拥有自己的网站
  • 做展示网站视频外链在线生成
  • 高新区规划建设局网站信息推广
  • 三视觉设计网站软文编辑器
  • 广告公司 名称合肥seo推广排名
  • 宿迁网站制作注册网站
  • 携程网站票面价含机场建设费吗公司网站建设
  • 延边网站开发谷歌官网入口
  • 满山红网站建设20条优化措施
  • 江苏省住房城乡建设厅官方网站关键词查找的方法有以下几种
  • 分类信息网站织梦模板做网络推广
  • 呢图网站网易企业邮箱