本文主要介绍了一个C元编程语言入门的详细讲解实例。里面包含了详细的基本概念和应用实例,可以供有需要的朋友参考,希望能有所帮助。
目录
模板通用初级函数模板友元模板参数元编程基本概念变量参数模板
模板
由于模板元编程需要基于面向对象,如果有问题可以先补充一些C面向对象的知识:
c面向对象就够了。
泛型初步
因为C是一种静态的强类型语言,一旦变量被创建,它的类型就不能被改变。如果要创建一个广泛使用的复杂类型,需要在int、float、double等基本类型的基础上逐个创建,非常麻烦。泛型编程的诞生就是为了简化这个过程。
可以容纳不同数据类型作为成员的类称为模板类,基本方法是在类声明中添加一行模板声明代码。
Typename t,下一行是类myClass,它的调用进程是myClassT m。
下面列出了一些例子。
#includeiostream
使用命名空间std
模板类型名C
结构摘要{
c真实;//real是c类型的。
C im
摘要(真实的,最小的)
real=inReal
im=inIm
}
void printVal(){
cout ' abstract:' real ' ' im ' I ' endl;
};
抽象多元(抽象值){
c temp=real * val . real-im * val . im;
im=real * val . real im * val . im;
真实=临时;
返回* this
};
};
int main(){
Abstractfloat fTemp{1,2 };//C类型是浮点型
ft EMP . multi(ft EMP);
ft EMP . print val();
系统(“暂停”);
返回0;
}
函数模板
当然,上面的multi不能实现两个不同类型抽象之间的乘法,所以可以把multi函数改为
模板类型名称T
AbstractC multi(抽象值){
c temp=real * val . real-im * val . im;
im=real * val . real im * val . im;
真实=临时;
返回* this
}
这样就可以实现以下功能。
int main(){
Abstractfloat fTemp{1,2 };
Abstractint iTemp{1,2 };
ft EMP . multi(iTemp);
ft EMP . print val();
get real(ft EMP);
系统(“暂停”);
返回0;
}
友元
类有普通类的一些属性,比如struct和class的区别,public,protected和private的属性,friends。模板的声明特性也可以应用于函数,例如
#includeiostream
使用命名空间std
模板类型名C
类别摘要{
c真实;
C im
公共:
摘要(真实的,最小的)
real=inReal
im=inIm
}
void printVal(){
cout ' abstract:' real ' ' im ' I ' endl;
};
抽象多元(抽象值){
c temp=real * val . real-im * val . im;
im=real * val . real im * val . im;
真实=临时;
返回* this
}
template typename T friend void get real(abstract num);//宣好友袁
};
模板类型名C
void getReal(AbstractC num){
coutnum.realendl
}
int main(){
Abstractfloat fTemp{1,2 };
ft EMP . multi(ft EMP);
ft EMP . print val();
get real(ft EMP);
系统(“暂停”);
返回0;
}
需要注意的是,在模板类中声明友元时,其前缀typename T中的类型ID一定不能与现有的类型ID重复,否则编译会失败。
函数模板也叫算法,因为它可以解决不同的数据类型,是函数或方法实例的抽象。
模板参数
如果模板被理解为一个类型声明的函数,那么模板也应该有一些函数所具有的功能。首先,它的模板参数可以包含实际的类型参数,比如
templatetypename T,int max
类别测试{}
调用时,可以写成
Testint,256像素;
模板还支持默认参数,可以按如下方式实现
templatetypename T=int,int max=256
类别测试{}
测试pixle
除了数据类型和值,模板本身也可以用作模板参数。例如,以下形式是合法的。
模板类型名T,模板类型名类C
结构测试{
CT * val
测试(联系类型*无效){
val=inVal
}
};
int main(){
Abstractint fTemp{1,2 };
Testint,抽象测试(ft EMP);
test . val-print val();
系统(“暂停”);
返回0;
}
结果是
PS E:\Code\cpp g,\generic.cpp
PS E:\Code\cpp。\a.exe
摘要:1 2i
请按任意键继续。
需要注意的是,模板类中定义的模板类需要实例化,否则会出错,所以在测试中,模板类是以指针的形式创建的。
型函数
输入或输出为数据类型的函数是类型函数。在C语言中,sizeof是一个类型函数。它的输入是数据类型,输出是数据类型所需的内存空间。
在C 11中,使用可以实现数据类型给定的函数,使用方法类似于typedef。
模板类型名称T
结构测试{
使用type=T;
}
元编程的基本概念
元编程是泛型编程的超集,两者本质上都是针对不同数据类型的算法,而后者更注重传入参数的通用性。如果元编程被分为四个级别
没有计算
操作员连接的操作
编译时有选择等非递归计算。
编译时的递归操作
那么泛型编程可以算是第一种元编程,或者说它更注重参数的传入传出过程,而元编程更注重不同数据类型的选择过程。
例如,我们可以实现一个最多包含三个元素的元组。其思想是三元元素可以看作一个二元元组和一个参数的组合;二元元组可以看作是一元元组和参数的组合;一元元组是基本数据类型的变量。在实现这个元组的过程中,除了赋值过程中的泛型,还需要判断当前实现的元组元素的个数。如果它的初始化参数是三个,就需要递归地创建变量,直到赋值参数是一个。它是这样实现的
类别Nil { };
//主模板
模板类型名T1=Nil,类型名T2=Nil,类型名T3=Nil
结构元组:元组2,T3{
t1x;
使用Base=TupleT2,T3;//三元元组基于二元元组
//返回值是TupleT2,T3指针类型的base()函数
//static_cast将此转换为类型Base*
base * base(){ return static _ cast base *(this);}
const Base * Base()const { return static _ cast const Base *(this);}
//构造函数继承二进制元组,在这个类中构造X的同时构造基类tuple 2,T3。
元组(常数T1 t1,常数T2 t2,常数T3 t3)
:Base{t2,t3},x{t1}{}
};
模板类型名T1
结构组1{
t1x;
};
模板类型名T1,类型名T2
结构连音1,T2:连音2{
t1x;
使用Base=TupleT2
Base * Base(){ return static _ cast const Base *(this);}
const Base * Base()const { return static _ cast const Base *(this);}
元组(常数T1 t1,常数T2 t2):Base{t2},x{t1}{}
};
模板类型名T1,类型名T2,类型名T3
void print_elements(ostream os,const TupleT1,T2,T3 t){
ost.x ',';
print_elements(os,* t . base());
}
模板类型名T1,类型名T2
void print_elements(ostream os,const TupleT1,T2 t){
ost.x ',';
print_elements(os,* t . base());
}
模板类型名T1
void print_elements(ostream os,const tuple 1t){
ost.x
}
//运算符重载
模板类型名T1,类型名T2,类型名T3
ostream运算符(ostream os,const TupleT1,T2,T3 t){
OS“{ 0 }”;
print_elements(os,t);
OS“}”;
返回OS;
}
int main(){
Tupleint,double,char x{1,2.5,' a ' };
coutxendl
系统(“暂停”);
返回0;
}
输出结果是
PS E:\Code\cpp g,\generic.cpp
PS E:\Code\cpp。\a.exe
{1,2.5,a}
可变参数模板
上述实现过程非常繁琐,而且元组中的元素数量有限。如果在标准库中使用上述书写方式,那么标准库中除了这个元组之外,什么也写不出来。幸运的是,C模板提供了可变参数的功能。例如,我们可以先把打印模板函数写成
//键入名称.t代表一个可变参数。
模板类型名T1,类型名.T
void print_elements(ostream os,const TupleT1,T.t){
ost.x ',';
print_elements(os,* t . base());
}
模板类型名T1
void print_elements(ostream os,const tuple 1t){
ost.x
}
模板类型名.T
牡蛎运算符(ostream os,const TupleT.t){
操作系统“{ 0 }”;
print_elements(os,t);
OS“}”;
返回OS;
}
其输出结果为
PS E:\Code\cpp g,\generic.cpp
PS E:\Code\cpp .\a.exe
{1,2.5,a}
请按任意键继续。
然后将元组也做相同的更改
模板类型名T1,类型名.T
结构元组:元组.{
t1x
使用基数=连音.//N ^ 1元元组以普通元元组为基
base * base(){ return static _ cast base *(this);}
const Base * Base()const { return static _ cast const Base *(this);}
//注意T.的书写格式
元组(常数T1 t1,常数T.t):Base{t.},x{t1}{}
};
模板类型名称T
结构连音{
t x;
};
/*
打印模板
*/
int main(){
Tuplestring,double,int,char tt('hello ',1.5,1,' a ');
coutttendl
系统("暂停");
返回0;
}
其输出结果为
PS E:\Code\cpp g,\generic.cpp
PS E:\Code\cpp .\a.exe
{你好,1.5,1,a}
以上就是C元编程语言初步入门详解的详细内容,更多关于C元编程语言初步的资料请关注我们其它相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。