模板的全局特化

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

一、函数模板的特化

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

#include <stdio.h>
#include <stdlib.h>
#include <typeinfo>

template <typename T>
void func(T a);

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

int main()
{
    int value = 10;
    func(value);
    
    return 0;
}

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

template <typename T>
void func(T a);

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

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

假如我们使用 func(10.0)

#include <stdio.h>
#include <stdlib.h>
#include <typeinfo>

template <typename T>
void func(T a);

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

int main()
{
    int value = 10;
    func(value);

    func(10.0);
    return 0;
}

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

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

#include <stdio.h>
#include <stdlib.h>
#include <typeinfo>

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

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

int main()
{
    int value = 10;
    func(value);

    func(10.0);
    return 0;
}

只是把声明改成了实现:

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

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

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

#include <stdio.h>
#include <stdlib.h>
#include <typeinfo>

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

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

int main()
{
    int value = 10;
    func(value);

    return 0;
}

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

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

二、类模板的特化

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

#include <stdio.h>
#include <stdlib.h>

template <typename T>
class S;

template<>
class S<int> 
{
public:
    void msg() 
    {
        printf("fully specialized (S<void>::msg())\n");
    }
};


int main()
{
    S<int> test1;
    test1.msg();
    // S<void> test2; //这里若要正常使用,则上面的S声明必须要实现,因为S没有void版本的特化。
    // test2.msg();
    return 0;
}

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值