网站制作可能出现的问题,正规网页设计培训怎么样,七米网站建设推广优化,展台引言与概述
C模板机制允许在定义类#xff0c;函数#xff0c;类型别名的时候将类型或值当作参数#xff0c;这样定义的类和函数在运行时间和空间效率上并不逊色于手工打造的非通用的代码。
模板提供的代码是类型安全的。
模板是一种编译时期的机制#xff0c;与手工编写…引言与概述
C模板机制允许在定义类函数类型别名的时候将类型或值当作参数这样定义的类和函数在运行时间和空间效率上并不逊色于手工打造的非通用的代码。
模板提供的代码是类型安全的。
模板是一种编译时期的机制与手工编写的代码相比并不会产生任何运行期开销。
对模板来说只有当一个成员函数被使用时才会被生成代码。
一个通用的组件应该从一个或多个具体实例泛化而来而不是简单的从第一原理直接而来。 即我们可以先写一个具体的函数或者类然后改成泛化类型。
模板简介
一个简单的模板
template typename C
class String {
public:String();explicit String(const C* c);//.....
private:static const int short_max 15;//用于短字符串的优化int sz;C* ptr;
};一个模板类的声明与普通class的声明差别不大只需要添加关键字和将需要泛化的类型进行替换。
模板成员函数也可以不用定义在类内也可以在外部定义但模板成员函数本身还是一个模板所以要显式声明一个模板
templatetypename C
StringC::String()
sz(0),ptr(nullptr)
{}模板实例化
模板实例化从一个模板和一个模板实参列表生成一个类或者一个函数的过程。
{Stringchar str;
}即可以进行变量的声明注意这里我们只创建了对象即这个类型String char 编译器会为其生成默认构造函数和析构函数不使用的成员对象或者函数则不会生成。
模板提供了一种用少量代码来生成大量代码的机制但我们要小心实例代码的泛滥造成内存的大量占用。 通过组合模板和简单内联可以消除很多直接或者间接函数调用的开销。
模板参数
模板机制的最大弱点是无法直接表达对模板参数的要求。
template Container Cont, typename Elemrequires Equal_comparableCont::value_type, Elem()
int find_index(Cont c, Elem e);但我们可以这写来进行模板参数的检查。 在C20 出现了concept这种技术可以帮助我们进行对模板参数要求的检查。
但这种检查是在编译过程中非常晚的时刻进行的而且是在抽象层次很低的层次上运行的帮助有限。
成员类型别名
如果我们想要在类外使用模板参数目前只有使用成员类型别名这种方法
template typename C
class String {
public:using value_type T;
};static成员
一个static的成员只有被真正使用时才被定义。
template typename T
struct X
{static int a;static int b;
};
int* p Xint::a;如果这就是全部代码那么 a 会被报错为无定意而b就不会。
模板与virtual
模板成员函数不能是虚函数如果使用那么为虚函数实现的传统技巧虚表就很难使用并且链接器的复杂性也会很高。
模板与嵌入类型
在模板中尽量避免嵌入类型除非它们真正依赖所有的模板参数。
模板与友元
template typename T
class B;template typename T
void A(const BT b);template typename T
class B {
public:friend void A(const BT b);
};友元后面的是必须的它指明了友元是一个模板函数如果没有则友元函数被假定为非模板函数。友元函数只有被使用时才会被实例化。
友元的设计目的是为了表达一小群紧密相关的概念如果友元关系很复杂那么一定是一个设计错误。
源码组织
使用模板组织源码有三种很明显的方法
在一个编译单元中在使用模板前包含其定义在一个编译单元中在使用模板前(只)包含其声明。在模板稍后的位置(或者使用之后)包含模板定义在一个编译单元中在使用模板前(只)包含其声明。在其他编译单元中包含其定义。
很遗憾的是C并不支持第三种实现方式。
如果一个类模板的布局或者是一个内联函数模板的定义发生了改变那么使用该类或者该函数的代码都要重新编译。
建议
使用模板用于很多实参类型的算法用模板表示容器注意template class T和template typename T意义相同当设计一个模板时首先设计和调试非模板版本随后添加参数将其泛化模板是类型安全的但检查的时机太晚了当设计一个模板时仔细思考concept它对模板参数的要求如果一个类模板必须是可拷贝的则为它定义一个非模板的拷贝构造函数和拷贝复制运算符如果一个类模板必须是可移动的则为它定义一个非模板的移动构造函数和移动复制运算符虚函数不能是成员模板函数只有当一个类型依赖类模板的所有实参时才将其定义为模板成员使用函数模板推断类模板实参类型对多种不同的实参类型重载函数模板来获得相同语义借助实参带入失败机制为程序提供正确的候选函数集使用模板别名简化符号隐藏实现细节C不支持模板分别编译在每个用到模板的编译单元中都#include模板定义使用普通函数作为接口编不能用模板处理的代码将大的模板和较严重依赖上下文的模板分开编译 没事的不论未来如何太阳一定都会升起没事的不论未来如何太阳一定都会升起没事的不论未来如何太阳一定都会升起