模板技巧
不看不知道,一看吓一跳。没想到,模板使用还有这么多大学问和小技巧。这正合了那句老话:万物自有其生存之理;看来前人之言-存在即合理,诚不欺我。
你使用过数组嘛?废话,编程怎么可能不用数组的!那么,你使用数组时会遇到数组大小需要在使用时才能确定的情况嘛?上得山多终遇虎,对于经常编程的人来说,这自然也是经常遇到过这样的问题的呢。既然遇到过,那你自然有解决之法呢。如果在C#或是Java中,这个问题倒是十分容易解决,用ArrayList就可以轻而易举的解决了;如果在C++中嘛,用标准的C++语法恐怕要费点功夫了,不过如果采用STL嘛,倒也不难解决,用vector就可轻易的办到了。问题是,如果一定要你用数组来完成,而不借助其他容器类,你该怎么办?没辙了吧,^_^!不急,既然我们谈模板,那么模板自然是有解决之道了。没错,我要谈的就是采用模板的非类型模板参数来解决这个问题。
非类型模板参数?没搞错吧,我经常用模板,都是定义类型参数,然后使用时再用实际类型去替换类型参数的,难道模板还允许像普通函数那样定义一个普通的形参?没错,你说对了,模板确实允许这样定义,而且使用它正好可以解决我们前面提到的问题。为免枯燥,我们胡乱选个例子加以说明吧。
你能者多劳,同时带了5个班的学生,每个班的学生人数嘛,自然不一样呢;现在你需要要统计每个班上学生的总成绩和平均成绩,你该怎么办?显然,这是一个典型的不定数目数组问题,我们试试用模板来解决:
2template <typename int NUM>
3class grade{
4public:
5 grade();
6 int average();
7 int sum();
8 int student[NUM];
9};
10
11template <typename int NUM>
12inline int grade<NUM>::average(){
13 if(NUM)
14 return sum()/NUM;
15}
16
17template <typename int NUM>
18inline grade<NUM>::grade(){
19 for(int i=0;i<NUM;i++){
20 student[i]=0;
21 }
22}
23
24template <typename int NUM>
25inline int grade<NUM>::sum(){
26 int sum=0;
27 for(int i=0;i<NUM;++i)
28 sum+=student[i];
29 return sum;
30}
31
32int main(){
33 grade<10> gr;
34 for(int i=0;i<10;++i){
35 gr.student[i]=i+1;
36 }
37 std::cout<<gr.sum()<<std::endl;
38 std::cout<<gr.average()<<std::endl;
39}
上面的代码,我想你一定明白了,很简单,不是嘛。我们采用模板参数NUM来给定班上学生的人数,然后数组就可以接受这个参数来作为数组的大小了,使用时,我们根据每个班的学生给出具体的实参就可以了,5个班?小kiss,100个班照样解决。怎么样?对模板非类型参数有何感想。可能有人会说,这么简单的问题,我不用模板照样可以解决。没错,这个问题的解决方案多着呢。看看,钻牛角尖了不是。任何问题,解决方案何止一种,我这里说这个例子无非是打个比方说说非类型模板参数的使用和用法。
俗语云:他山之石,可以攻玉。妙用模板参数类型,一定会使你的程序如虎添翼。