• 非类型模板参数+模板的特化


    目录

    一、非类型模板参数

    二、模板的特化

    (一)函数模板特化

    (二)类模板举例

    1. 全特化

    2. 偏特化


    一、非类型模板参数

    • 模板参数分类:类型形参非类型形参
    • 类型形参即:出现在模板参数列表中,跟在class或者typename之类的参数类型名称。
    • 非类型形参,就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用。
    • 注意:
      1. 浮点数、类对象以及字符串是不允许作为非类型模板参数的。
      2. 非类型的模板参数必须在编译期就能确认结果。
    1. #include
    2. using namespace std;
    3. template<class T,size_t N>
    4. class Stack
    5. {
    6. private:
    7. T _a[N];
    8. };
    9. int main()
    10. {
    11. Stack<int, 10>s1;
    12. Stack<double, 1000>s2;
    13. cout << sizeof(s1) / sizeof(int) << endl;//10
    14. cout << sizeof(s2) / sizeof(double);//1000
    15. return 0;
    16. }

     

    二、模板的特化

    • 通常情况下,使用模板可以实现一些与类型无关的代码,但对于一些特殊类型的可能会得到一些错误的结果,需要特殊处理
    • 在原模板类的基础上,针对特殊类型所进行特殊化的实现方式。模板特化中分为函数模板特化类模板特化

    (一)函数模板特化

    •  函数模板的特化步骤:
    • 1. 必须要先有一个基础的函数模板
    • 2. 关键字template后面接一对空的尖括号<>
    • 3. 函数名后跟一对尖括号,尖括号中指定需要特化的类型
    • 4. 函数形参表: 必须要和模板函数的基础参数类型完全相同,如果不同编译器可能会报一些奇怪的错误。
    1. // 通用模板函数
    2. template <typename T>
    3. bool isGreater(T a, T b)
    4. {
    5. return a > b;
    6. }
    7. // 特化版本针对字符类型
    8. template <>
    9. bool isGreater<char>(char a, char b)
    10. {
    11. cout << "Using specialized version for characters." << endl;
    12. return toupper(a) > toupper(b);
    13. }
    1. #include
    2. #include
    3. using namespace std;
    4. // 通用模板函数
    5. template <typename T>
    6. bool isGreater(T a, T b) {
    7. return a > b;
    8. }
    9. // 特化版本针对字符类型
    10. template <>
    11. bool isGreater<char>(char a, char b) {
    12. cout << "Using specialized version for characters." << endl;
    13. return toupper(a) > toupper(b);
    14. }
    15. int main()
    16. {
    17. if (isGreater(69, 66))
    18. {
    19. cout << "69 is greater than 66" << endl;
    20. }
    21. else
    22. {
    23. cout << "69 is not greater than 66" << endl;
    24. }
    25. if (isGreater('G', 'B'))
    26. {
    27. cout << "G is greater than B" << endl;
    28. }
    29. else
    30. {
    31. cout << "G is not greater than B" << endl;
    32. }
    33. return 0;
    34. }

    (二)类模板举例

    1. 全特化

    • 全特化即是将模板参数列表中所有的参数都确定化
    1. #include
    2. using namespace std;
    3. template<class T1, class T2>
    4. class Data
    5. {
    6. public:
    7. Data()
    8. {
    9. cout << "Data" << endl;
    10. }
    11. private:
    12. T1 _d1;
    13. T2 _d2;
    14. };
    15. template<>
    16. class Data<int, char>
    17. {
    18. public:
    19. Data()
    20. {
    21. cout << "Data" << endl;
    22. }
    23. private:
    24. int _d1;
    25. char _d2;
    26. };
    27. int main()
    28. {
    29. Data<int, int> d1;
    30. Data<int, char> d2;
    31. return 0;
    32. }

     

    2. 偏特化

    • 偏特化:任何针对模版参数进一步进行条件限制设计的特化版本
    • 偏特化有以下两种表现方式:
    • 情况一部分特化:将模板参数类表中的一部分参数特化 
    1. // 将第二个参数特化为int
    2. template <class T1>
    3. class Dataint>
    4. {
    5. public:
    6. Data() { cout << "Data" << endl; }
    7. private:
    8. T1 _d1;
    9. int _d2;
    10. };

     

    • 情况二参数更进一步的限制:偏特化并不仅仅是指特化部分参数,而是针对模板参数更进一步的条件限制所设计出来的一个特化版本。
    1. //两个参数偏特化为指针类型
    2. template <typename T1, typename T2>
    3. class Data
    4. {
    5. public:
    6. Data()
    7. {
    8. cout << "Data" << endl;
    9. }
    10. private:
    11. T1 _d1;
    12. T2 _d2;
    13. };
    14. //两个参数偏特化为引用类型
    15. template <typename T1, typename T2>
    16. class Data
    17. {
    18. public:
    19. Data(const T1& d1, const T2& d2)
    20. : _d1(d1)
    21. , _d2(d2)
    22. {
    23. cout << "Data" << endl;
    24. }
    25. private:
    26. const T1& _d1;
    27. const T2& _d2;
    28. };

     

    1. #include
    2. using namespace std;
    3. template<class T1, class T2>
    4. class Data
    5. {
    6. public:
    7. Data()
    8. {
    9. cout << "Data" << endl;
    10. }
    11. private:
    12. T1 _d1;
    13. T2 _d2;
    14. };
    15. template <typename T1, typename T2>
    16. class Data
    17. {
    18. public:
    19. Data()
    20. {
    21. cout << "Data" << endl;
    22. }
    23. private:
    24. T1* _d1;
    25. T2* _d2;
    26. };
    27. template <typename T1, typename T2>
    28. class Data
    29. {
    30. public:
    31. Data(const T1& d1, const T2& d2)
    32. : _d1(d1)
    33. , _d2(d2)
    34. {
    35. cout << "Data" << endl;
    36. }
    37. private:
    38. const T1& _d1;
    39. const T2& _d2;
    40. };
    41. int main()
    42. {
    43. Data<int, char>d;
    44. Data<int*, int*> d1;
    45. Data<const int&, const int&> d2(5, 10); // 提供初始化值
    46. return 0;
    47. }

  • 相关阅读:
    在小程序中使用vant,应用Mobx实现全局数据共享
    高品质建筑红模板与耐久黑色覆膜清水模板:建筑质量的双重守护者
    scipy在控制理论的应用
    我是怎么从软件测试转到自动化测试岗的?亲身经历分享
    ASO优化:关键词该怎么选
    flowable 监听获取流程下一节点
    文件用手机拍照片打印时,打印出来总是有黑阴影,如何去掉黑色阴影打印清晰的图片
    3.18 最大单词长度——力扣
    抢抓泛娱乐社交出海新风口!Flat Ads深圳沙龙活动引爆海外市场
    Java注解(4):一个真实的Elasticsearch案例
  • 原文地址:https://blog.csdn.net/m0_63783532/article/details/133830054