您的位置:首页 > 编程语言 > C语言/C++

编程学习笔记之c++相关::模板元的学习

2016-01-23 18:49 260 查看
      考虑这种情况,您的程序需要比较两个数值,然后返回较大的那个,数值的类型包括int、float和char,您要如何写代码?当然您可以选择传统的做法,就是乖乖写三个函数,分别是int类型、float类型和char类型。但既然我们的c++犀利在功能丰富上,所以我们当然要使用高大上的技巧,这就是此篇要讲的函数模板。先看看函数模板是如何解决上述要求的:

#include <iostream>
#include <string>
using namespace std;

template <typename T>
T max(T a, T b)
{
return (a > b) ? a : b;
}

int main(void)
{
int i1, i2;
float f1, f2;
char c1, c2;

i1 = 2;
i2 = 8;
cout << "较大整数是:" << max<int>(i1, i2) << endl;

f1 = 1.5;
f2 = 3.14;
cout << "较大浮点数是:" << max<float>(1.5, 3.14) << endl;

c1 = 'b';
c2 = 't';
cout << "较大字符是:" << max<char>(c1, c2) << endl;
return 0;
}

里面的template <typename T>就是我们所使用的函数模板,函数模板本身并不占用内存或生成可执行代码等,但是一旦当我们在程序中使用时,就会生成一个模板函数,而模板函数是实例存在的。以上面为例,我们写的那个max的函数模板,本身是不生成任何代码的,可是我们在cout中使用【max<int>(i1, i2)】时,max中所有的T就会被替换为尖括号中的参数int,然后程序按照max的文本在代码区中为max生成一个int版的二进制可执行代码。至于另外两个float和char,和int都是一样的道理,所以在上面的梨子中,程序一共生成了3个可调用函数,分别是max的int版本、float版本和char版本,它们位于不同的代码区地址。

      也许有朋友会问,我可以省事点,把上面的【max<int>(i1, i2)】写成【max(i1, i2)】形式吗?答案是也可以,编译器会把i1与i2本身的类型int拿给程序看。但强烈不建议这么做,因为这是比较冒险的。比如下面这段代码就无法通过编译了:

#include <iostream>
#include <string>
using namespace std;

template<typename T1,typename T2>
T1 numadd(T1 a, T2 b)
{
b = 3;
return a + b;
}

int main(void)
{
int i = 9;
numadd(i); //无法通过编译的错误代码
numadd<int,int>(i,i); //正确的代码
return 0;
}
这是因为在numadd(i),虽然把i的类型int拿过去了,但T2程序就不知道该怎么办了。

      此外,能给函数模板拿来当参数的,除了类型意外,“变量”也可以。上一句的变量二字为何要加引号,因为此处变量不是真正意义上的变量,而是常量伪装的变量,看代码:

#include <iostream>
#include <string>
using namespace std;

#include <iostream>
#include <string>
using namespace std;

template <typename T, int size>
void forprin(T a)
{
T i;
for (i = 0; i < size; i++)
cout << a;
}

int main()
{
int k = 5;
forprin<int, k>(k); //错误的写法!
forprin<int, 5>(k); //正确的写法.

return 0;
}
其中第一个forprin的用法是无法通过的,这是因为函数模板生成模板函数时,是一个编译期的行为,而编译期是无法得到k的具体数值的,所以第二个模板参数必须要使用常量而非变量

      最后还要说明一点,函数模板是可以重载的,比如下面三个函数模板:

#include <iostream>
#include <string>
using namespace std;

#include <iostream>
#include <string>
using namespace std;

template <typename T>
void fun(T a)
{
cout << "第一个函数模板" << endl;
}
/**********************************************/
template <typename T,typename T2>
void fun(T a)
{
cout << "尖括号模板参数不同" << endl;
}
/********************************************/
template <typename T>
void fun(T a, T b)
{
cout << "圆括号参数不同" << endl;
}

int main()
{
fun<int>(1);
fun<int ,char>(2);
fun<int>(1, 2);
return 0;
}
其中的函数模板fun名字都是一样的,但到了main函数中,程序会根据fun调用的具体情况【有参数个数不同的,有模板参数不同的等等】,再来决定具体生成哪个模板函数。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  模板 template