做类似58同城的网站,ppt免费模板大全网站,wordpress 拉不到底,企业门户网站开发源码标题#xff1a;C : 模板初阶
水墨不写bug 正文开始#xff1a; C语言的问题 #xff1a; 写不完的swap函数 在学习C语言时#xff0c;我们有一个经常使用的函数swap函数#xff0c;它可以将两个对象的值交换。 我们通常这样实现它#xff1a; void swap(int t1,int t2)…标题C : 模板初阶
水墨不写bug 正文开始 C语言的问题 写不完的swap函数 在学习C语言时我们有一个经常使用的函数swap函数它可以将两个对象的值交换。 我们通常这样实现它
void swap(int t1,int t2)
{int tem t1;t1 t2;t2 tem;
} 这是很简单的函数。如果我们想交换其他类型的对象就需要用到函数重载
void swap(int t1,int t2){int tem t1;t1 t2;t2 tem;}
void swap(float t1, float t2){ float tem t1;t1 t2;t2 tem;}
void swap(double t1, double t2){ double tem t1;t1 t2;t2 tem;}
void swap(char t1, char t2){ char tem t1;t1 t2;t2 tem;}
void swap(long t1, long t2){ long tem t1;t1 t2;t2 tem;}
//...但是内置类型的指针理论上可以达到n级指针n可以趋于无限大除此之外还有自定义类型。这样一来你就会发现类型是无法枚举的一个swap函数需要实现一种类型的交换那么swap函数是写不完的 人工解决重复写同一个逻辑仅仅是类型不同的代码是很低效的为了解决这个问题C引入模板的概念 顾名思义模板就是模板作用就是印出不同的东西这个东西就是swap函数 一模板简介 模板是C相对于C的一个新的语法他需要用到关键字template模板如果我们用模板来实现swap函数就可这样写 template typename T
void swap(T t1, T t2)
{T tem t1;t1 t2;t2 tem;
} templatetypename或class 模板参数 模板主体 就是模板的基本形式。 要成功的调用模板函数也需要特定的条件 template class T
void swap(T t1, T t2)
{T tem t1;t1 t2;t2 tem;
}
/*void swap(int t1,int t2){int tem t1;t1 t2;t2 tem;}void swap(float t1, float t2){ float tem t1;t1 t2;t2 tem;}void swap(double t1, double t2){ double tem t1;t1 t2;t2 tem;}void swap(char t1, char t2){ char tem t1;t1 t2;t2 tem;}void swap(long t1, long t2){ long tem t1;t1 t2;t2 tem;}
*/
int main()
{int a 1, b 5;::swap(a, b);cout a b endl;return 0;
} 我们可以指定调用全局的swap模板函数完成对象的值交换。 1为什么模板可行模板的原理 在编译时编译器会 匹配 模板参数的类型如上例ab的类型都是整形所以编译器会根据根据函数的模板生成一份函数这份函数仅仅将 T模板参数 改成 匹配出的类型 void swap(int t1,int t2)
{int tem t1;t1 t2;t2 tem;
} 这样我们人工编写的工作量就减少了非常多因为一个理论上模板可以生成n个函数n可趋于无穷大。 2匹配冲突 由于交换的是两个参数的值当两个参数的类型不同时理论上不能交换此时编译器也会因为匹配类型冲突而报错 如何解决这个问题 i再增加一个模板参数(推荐) 由于只有一个模板参数 当推断类型既是int又是double时一个参数就应付不过来了所以需要再增加一个参数。两个模板参数就可以进行两次参数类型匹配
template class T1,class T2
void swap(T1 t1, T2 t2)
{auto tem t1;t1 t2;t2 tem;
} ##如果你是看了后面两种处理方式后又回来的那么你很敏锐发现了本例的问题其实本例也发生了类型转换 由于t1t2类型不一致所以在下面赋值时必然发生了类型转换可能导致精度丢失。但是这并不影响我们解决匹配冲突的方法因为在实际应用中我们一般不会让模板参数之间进行运算。这仅仅是本例的场景不太好使用多个模板来解决匹配冲突仍然是推荐的 ## ii,强制转换到一致 只能解决一些特例就拿下面这个函数模板来说
templateclass T
T Add(T t1,T t2)
{return t1 t2;
}void test2()
{int a 1;double b 5.6;double ret ::Add((double)a, b);cout ret;
} 将a强制类型转换到double可以使编译器对a和b类型匹配都是double这样是可以通过编译的但是这样操作的结果是不稳定的。强制类型转换必然意味着精度或者符号的丢失不到迫不得已不要使用强制类型转换 iii显示实例化(不再推演参数) 只能解决一些特例还是拿上面这个函数模板来说
templateclass T
T Add(T t1,T t2)
{return t1 t2;
}
void test2()
{int a 1;double b 5.6;double ret ::Adddouble(a, b);cout ret;
} 这也是可以通过编译的在模板名称后面加上参数类型意味着指定了生成的模板的匹配类型就是 这个指定的参数类型。由于指定了参数类型其本质也是发生了类型转换而类型转换是不推荐的。 总结 解决匹配冲突的方法 i再增加一个模板参数(推荐) ii,强制转换到一致 iii显示实例化(不再推演参数) 3模板实例化的条件 当全局已经有一个匹配的函数时模板就不会再生成新函数。 以这个例子来说 void swap(double t1, double t2){ double tem t1;t1 t2;t2 tem;}template class T
void swap(T t1, T t2)
{T tem t1;t1 t2;t2 tem;
}
void test1()
{double a 1;double b 5;::swap(a, b);cout a b endl;
} 模板匹配的类型是double由于全局已经有了类型是double的函数所以编译器不会再通过函数模板再生成一份swap函数。 编译器会优先匹配最合适的模板 template class T1,class T2
void swap(T1 t1, T2 t2)
{T1 tem t1;t1 t2;t2 tem;
}
template class T
void swap(T t1, T t2)
{T tem t1;t1 t2;t2 tem;
}
void test1()
{int a 1;double b 5;::swap(a, b);cout a b endl;
} 本例中由于ab两个变量的类型不同所以编译器会优先选择两个模板参数的swap函数而不是一个模板参数的swap。 在特殊情况也是可以编译通过的 void swap(int t1, int t2)
{ int tem t1; t1 t2; t2 tem;
}
void test1()
{int a 1;double b 5;::swap(a, b);cout a b endl;
} 总结 1.全局有完全匹配的函数编译器不再由模板生成函数直接使用现成的函数。 2.如果有多个模板编译器会选择最合适的模板来生成函数 3.类型不匹配没有模板也可以编译通过但是会发生类型转换导致精度丢失。 其实模板远不止这些本文仅仅是以函数模板为引子来讲解模板的语法而模板还包括类模板后者是实际中应用较多的。 类模板 就放 在将来为大家分享吧 目录
一模板简介
1为什么模板可行模板的原理
2匹配冲突
i再增加一个模板参数(推荐)
ii,强制转换到一致
iii显示实例化(不再推演参数)
总结
3模板的生成条件
总结 ~完
未经作者同意禁止转载