码迷,mamicode.com
首页 > 编程语言 > 详细

C++ template的一些高级用法(元编码,可变参数,仿函数,using使用方法)

时间:2015-04-02 13:24:02      阅读:214      评论:0      收藏:0      [点我收藏+]

标签:

1 .  通用函数可变参数模板

     对于有些时候,我们无法确切的知道,函数的参数个数时,而又不想过多的使用所谓的函数重载,那么就可以效仿下面的例子:

 1 #include<iostream>
 2 #include<Array>
 3 void showall() { return; }
 4 
 5 template <typename R1 ,typename...  Args>
 6 
 7 void showall(R1 var, Args...args) {
 8 
 9     std::cout << var << std::endl;
10     showall(args...);
11 }
12 
13 int main(int argc, char * args[]) {
14 
15     
16     showall(1, 2, 3, 4, 5);
17     showall("gxjun","dadw","dasds");
18     showall(1.0,2.0,3.5);
19     std::cin.get();
20     return 0;
21 }

在游戏开发中,时常会用到这样的模板,类型不确定,参数的个数不确定,所以需要用一种类似于递归的函数来处理。  第一个函数,表示的是在参数为0时,结束。

效果:

技术分享

2.  如何使用仿函数:

     首先仿函数的定义: ,仿函数也叫函数对象(Function Object, or Functor),定义就是任何可以像函数一样被调用的对象。一个普通的函数是函数对象,一个函数指针当然也是,广义上说任何定义了operator()的类对象都可以看作是函数对象。 (找到文档)

      其实,往直白的地方说,就是一个不是函数但是具有函数功能且用法和函数相同的对象(结构体或者类)。

下面举个栗子(用结构体实现函数功能):

  

 1 /*关于C++仿函数*/
 2 #include<iostream>
 3 #include<functional>
 4 using namespace std;
 5 using namespace std::placeholders;  
 6 
 7 template <typename R1 , typename R2>
 8 struct  Calc
 9 {
10     void add(R1 a) {
11         cout << a << endl;
12     };
13     void add_1(R1 a, R1 b) {
14         cout << a + b << endl;
15     }  
16 };
17 
18 int main(int argc, char * args[]) {
19 
20     //函数指针
21     void(Calc<int, double>::*fc)(int  a) = &Calc<int, double >::add;
22     // fc(25);
23     //显然上面的式子比较的麻烦
24     
25     Calc < int, int> calc;
26     auto  fun = bind(&Calc<int, int >::add, &calc, _1);
27     auto  fun_2 = bind(&Calc<int, int >::add_1, &calc, _1,_2);
28     fun(123);
29     fun_2(12,24);
30    cin.get();
31  return 0;
32 }

    对于bind()这个函数,开头的是地址,函数名,后面的是第一个列子中的Args....不定参数类型、

效果图为:

   技术分享

3. 使用using别名,函数指针,typdef来实现函数的调用

    虽然是寥寥的几行代码,但是功能在实际应用中,却会发挥很大的作用。

 1 //using别名使用用法
 2 #include<iostream>
 3 #include<windows.h>
 4 int calc() {
 5   //当为无参数时,返回0值
 6     return 0;
 7 }
 8 
 9 template <typename R1 ,typename...Args>
10 int calc(R1 a, Args...args) {
11 
12     return a + calc(args...);
13 }
14 
15 int main(int argc , char * args []) {
16 
17     //使用函数指针
18     int(*fun) (int ,int ,int ,int ) = calc;
19     system("echo 使用函数指针实现1~4累加");
20     std::cout << fun(1,2,3,4)<<std::endl;
21    //使用typedef来实现该功能
22     system("echo 使用typedef实现1~4累加");
23      typedef int(*Add)(int, int, int);
24      Add  Gadd = calc;
25      std::cout << Gadd(1, 2, 3) << std::endl;
26     //使用using别名来实现这么个功能
27     system("echo 使用using实现1~4累加");
28     using Func = int(*) (int, int, int, int);
29     Func func = calc;
30     std::cout << func(1, 2, 3, 4) << std::endl;
31     std::cin.get();
32  return 0;
33 }

效果图: 

技术分享

  4. C++模板元编程:

          对于模板元编程: 我的理解是,你所要的计算,在编译的时候,已经处理玩了,只需要在运行的时候输出结果即可!

    当我们每每学到模板元编程的时候,就会有一个混淆的词汇出现,哒,看------函数式编程。 到底什么是函数式编程呢?

    建议去看这篇文章,http://www.ruanyifeng.com/blog/2012/04/functional_programming.html  模板元编程用处广泛,

    我们知道当硬件条件限制的情况下,除了优化算法,还有一种途径,那就是用模板元编程。 现在就让我们来看看这个金典的应用吧!

    斐波那契数列的计算......

   

 1 #include<iostream>
 2 #include<time.h>
 3 #include<windows.h>
 4 /*
 5   斐波那契数列
 6    H(1)=H(0)=1;
 7    H(N)= H(N-1)+H(N-2);
 8 */
 9 using namespace std;
10 
11  /* 普通版普通版 */
12  using _int = long  ;    //使用别名
13  
14  _int feibona(_int ac) {
15     if (ac == 0||ac==1)  return 1;
16     return feibona(ac-1) +feibona(ac-2);
17 }
18 
19  /* 使用元编程 完全特化版 方法如下*/
20  template <_int N>
21  struct data {
22      //采用枚举
23      enum { res = data<N - 1>::res + data<N - 2>::res };
24  };
25 
26 template <>
27 struct data<1> {
28     //采用枚举
29     enum { res = 1L };
30 };
31 
32 template <>
33 struct data<0> {
34     //采用枚举
35     enum { res = 1L };
36 };
37 
38 
39 int main(int argc, char * args[]) {
40 
41     time_t  a ,b;
42     a = clock(); //开始记录时间
43     cout << data<45L>::res << endl;
44     b = clock(); //开始记录时间
45     system("echo 采用元编程所消耗的时间");
46     cout << (double)(b - a) / CLK_TCK<<"ms"<<endl;
47     a = clock();
48     cout << feibona(45L) << endl;
49     b = clock();
50     system("echo 采用普通的算法所消耗的时间");
51     cout << (double)(b - a) / CLK_TCK << "ms" << endl;
52     cin.get();
53     return 0;
54 }

  两者相对比的效果图:

 技术分享

C++ template的一些高级用法(元编码,可变参数,仿函数,using使用方法)

标签:

原文地址:http://www.cnblogs.com/gongxijun/p/4385838.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!