• 模板的全局特化


            模板的特化简单地理解就是明确参数的类型,而不是用 typename , 不管是函数模板,还是类模板,都可以实现特批。其语法为:template <> xxx,模板参数是空的。

    一、函数模板的特化

    如下最简单的一个函数模板特化:

    1. #include
    2. #include
    3. #include
    4. template <typename T>
    5. void func(T a);
    6. template<>
    7. void func(int value)
    8. {
    9. printf("type of T is: int, value = %d\n", value);
    10. }
    11. int main()
    12. {
    13. int value = 10;
    14. func(value);
    15. return 0;
    16. }

    首先是声明了一个函数模板:

    1. template <typename T>
    2. void func(T a);

    接下来就是特化这个函数模板,特化的参数类型就是 int 类型:

    1. template<>
    2. void func(int value)
    3. {
    4. printf("type of T is: int, value = %d\n", value);
    5. }

    假如我们使用 func(10.0)

    1. #include
    2. #include
    3. #include
    4. template <typename T>
    5. void func(T a);
    6. template<>
    7. void func(int value)
    8. {
    9. printf("type of T is: int, value = %d\n", value);
    10. }
    11. int main()
    12. {
    13. int value = 10;
    14. func(value);
    15. func(10.0);
    16. return 0;
    17. }

    则是编译错误的,提示我们没有实现对应类型 double 的模板:

     因为我们上面只是声明了一个函数模板,同时特化了一个 int 类型的模板,所以这样只能使用特化的那个版本。那要用其他类型版本的,该如何操作呢?其实就是要声明时同时定义就可以:

    1. #include
    2. #include
    3. #include
    4. template <typename T>
    5. void func(T a)
    6. {
    7. printf("type of T is: %s\n", typeid(T).name());
    8. }
    9. template<>
    10. void func(int value)
    11. {
    12. printf("type of T is: int, value = %d\n", value);
    13. }
    14. int main()
    15. {
    16. int value = 10;
    17. func(value);
    18. func(10.0);
    19. return 0;
    20. }

    只是把声明改成了实现:

    1. template <typename T>
    2. void func(T a)
    3. {
    4. printf("type of T is: %s\n", typeid(T).name());
    5. }

     实现使用时,int 类型参数使用了特化版本的函数,而 double 则使用普通版本的函数:

    我们知道,模板只有在使用的时候才会生成对应类型的代码,如果只是声明或定义时,是不会生成相应代码的;而这个特化的模板是否有相应类型的代码呢?有如下代码:
     

    1. #include
    2. #include
    3. #include
    4. template <typename T>
    5. void func(T a)
    6. {
    7. printf("type of T is: %s\n", typeid(T).name());
    8. }
    9. template<>
    10. void func(int value)
    11. {
    12. printf("type of T is: int, value = %d\n", value);
    13. }
    14. int main()
    15. {
    16. int value = 10;
    17. func(value);
    18. return 0;
    19. }

     可以看到只有一个特化出来对应的 int 版本的代码。如果多加一行代码:func(10.0) ,结果会是什么样的呢?

    可以看到多了一个 double 类型的模板代码。

    二、类模板的特化

    类模板的特化跟函数模板的特化相似的。

    1. #include
    2. #include
    3. template <typename T>
    4. class S;
    5. template<>
    6. class S<int>
    7. {
    8. public:
    9. void msg()
    10. {
    11. printf("fully specialized (S::msg())\n");
    12. }
    13. };
    14. int main()
    15. {
    16. S<int> test1;
    17. test1.msg();
    18. // S test2; //这里若要正常使用,则上面的S声明必须要实现,因为S没有void版本的特化。
    19. // test2.msg();
    20. return 0;
    21. }

     代码里只是声明了类模板 S,同时特化了 int 类型的类模板,正如注释里说的要想使用 S 的版本,则上面的必须是定义,而非声明。

  • 相关阅读:
    软考系统架构师知识点集锦六:项目管理
    科技云报道:AI写小说、绘画、剪视频,生成式AI更火了!
    ThreadLocal InheritableThreadLocal TransmittableThreadLocal简单使用
    Kotlin 协程 - 协程调度器 CoroutineDispatcher
    下载opencv
    如何实现应用程序的身份认证和数据加密?
    【linux】保存一份进程监视命令
    ky使用教程(基于fetch的小巧优雅js的http客服端)
    centos 利用selenium抓包
    【AI设计模式】05-检查点模式(CheckPoints):如何定期存储模型?
  • 原文地址:https://blog.csdn.net/tianyexing2008/article/details/126834570