Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2563615
  • 博文数量: 315
  • 博客积分: 3901
  • 博客等级: 少校
  • 技术积分: 3640
  • 用 户 组: 普通用户
  • 注册时间: 2011-05-08 15:32
个人简介

知乎:https://www.zhihu.com/people/monkey.d.luffy Android高级开发交流群2: 752871516

文章分类

全部博文(315)

文章存档

2019年(2)

2018年(1)

2016年(7)

2015年(32)

2014年(39)

2013年(109)

2012年(81)

2011年(44)

分类: C/C++

2013-05-19 16:20:31

    已经看到第三个视频了。重点当然还是模啦!这里主要就是模特化的一个用处:限定某些特定的模参数进行特化,其实挺有用的,就像管哥说的,可以防止你定义某些不支持的模参数而导致程序错误。
    步入正题,我就拿我工作的一个实例,就是关于Opengl渲染建筑面的case,当前Opengl绘制各种图形基本都采用数据+索引的方式,因此索引很重要,可以大幅度提高渲染效率和节省内存,因此索引组织好很关键。而索引的类型也是有讲究的,不是你想用什么类型就用什么类型,就像某些老牌机器不支持64位系统一样;当前Opengl好像已经不支持int类型的索引绘制方式了,我在工作中测试了,确实不行。但是对于建筑物的大量点而言,unsigned short类型已经足够用了。因此我打算限制我们索引为unsigned short类型,你定义其它的类型将无法使用我的索引空间。

    看代码:

点击(此处)折叠或打开

  1. #ifndef _SPECIALIZATION_DEF_
  2. #define _SPECIALIZATION_DEF_
  3. #include <string.h>

  4. /**
  5.  * @brief 模特化之限定参数类型【让编译器成为你的奴隶】
  6.  */

  7. ///< 这里我就拿我工作中实际的一个例子吧!!!glpainter在实际绘制建筑面的时候,
  8. ///< 需要顶点坐标和索引数据,而索引对数据类型是有要求的,新的opengl版本还不支持int类型,
  9. ///< 因此一般来讲,uint16 <=> unsigned short 就ok了。因此索引类型,我采用了宏,方便修改.
  10. ///< 这里我们就利用模版特化的“功效”来实现只有某些类型可以被定义为索引类型...

  11. ///< ----------正常情况下我们希望支持各种类型T----------
  12. template <typename T>
  13. class BuildingIndex            ///< 建筑物索引数据类型
  14. {
  15. public:
  16.     BuildingIndex(T size)
  17.     {
  18.         index = new T[(sizeof(T) * size)];
  19.         if (index)
  20.         {
  21.             memset(index, '0', (sizeof(T) * size));
  22.         }
  23.     }
  24.     ~BuildingIndex()
  25.     {
  26.         if (index)
  27.         {
  28.             delete[] index;
  29.         }
  30.     }
  31. public:
  32.     T * index;
  33. };

  34. ///< ----------由于目前最新的opengl不支持int类型的索引,因此将剔除该定义方式,这样你定义了就会报错----------
  35. template <>
  36. class BuildingIndex    <int>        ///< 建筑物索引数据类型不支持int
  37. {
  38. public:
  39.     BuildingIndex(int size)
  40.     {

  41.     }
  42.     ~BuildingIndex()
  43.     {

  44.     }
  45. public:
  46.     //这里不再提供index,看你怎么办
  47. };


  48. ///< ----------管哥还说了,可以反其道而行,就是申明一个模版,不实现,把能够定义的索引类型例举出来----------
  49. template <typename T>
  50. struct ALL;

  51. template <>
  52. struct ALL <unsigned short>
  53. {

  54. };

  55. template <>
  56. struct ALL <char>
  57. {

  58. };

  59. #endif //_SPECIALIZATION_DEF_
main.c文件测试【环境是VS,管哥的视频教学就在windows环境下,而且VS也是很强大的,虽然我一直在linux下开发】:

点击(此处)折叠或打开

  1. // Specialization.cpp : 定义控制台应用程序的入口点。
  2. //

  3. #include "stdafx.h"
  4. #include "Specializationdef.h"
  5. #include <iostream>

  6. using namespace std;


  7. int _tmain(int argc, _TCHAR* argv[])
  8. {
  9.     ///< 定义索引类型为uint16(unsigned short)类型的
  10.     unsigned short i;
  11.     BuildingIndex<unsigned short> bIndex(50);
  12.     if (NULL == bIndex.index)
  13.     {
  14.         return 1;
  15.     }
  16.     for(i = 0; i < 50; ++i)    ///< 假设索引就是这样,然后赋上值就可以用了...
  17.     {
  18.         bIndex.index[0] = i;
  19.     }

  20.     ///< 我们想定义int型的索引类型,看行不行???
  21.     BuildingIndex<int> bIndexWrong(50);
  22.     /*if (NULL == bIndexWrong.index) ///<
  23.     {
  24.     return 1;
  25.     }*/
  26.     BuildingIndex<double> bIndexRight(50); ///< double也OK
  27.     bIndexRight.index[0] = 10.10;

  28.     ///< 测试下反其道而行
  29.     ALL<unsigned short> shAll;  // OK
  30.     ALL<char> chAll;            // OK
  31.     //ALL<int> shAll;           // NOT OK

  32.     getchar();
  33.     return 0;
  34. }


阅读(2339) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~