C++模版:偏特化和函数模版的小技巧

本文介绍了C++模板偏特化的概念及其实现方法,包括如何通过偏特化实现类型过滤,并探讨了函数模板参数推导的便利性和设计选择。
偏特化就是部分特化。
利用模版的偏特化,可以实现一些类型过滤。
比如,我想让一个类模版指定类型如int能编译过,其他编译不过,代码实现如下:


template <typename T>
class A;

template<>
class A<int>
{

};

int main()
{
    A<int> a;
    A<double> b; //error
    return 0;
}


以上代码,通用的模版没有实现,只实现了int的特化模版,这样class A就只接受int类型的模版形参了。

同理,我们也能实现让指定类型如int不能编译过,其他都能编译过,代码如下:


template <typename T>
class A
{};

template<>
class A<int>;

int main()
{
    A<int> a; //error
    A<double> b;
    return 0;
}


函数模版比类模版多了一个参数传入的过程,所以可以省略模版参数,因为可以从传入的参数推导。比如:


#include<iostream>
using namespace std;

template< typename T>
int func(T a, T b)
{
    cout << a + b << endl;
    return a + b; 
}

int main()
{
    func<int>(3, 4);
    func(3, 4);
    return 0;
}


func<int>(3, 4);和func(3, 4);调用是等价的。

关于函数模版可以推导,这里有一个有趣的问题:

如果要实现一个类型转化的模版,如下两种定义,那种比较好?

template<typename Dst, typename Src> Dst convert(Src src)

template<typename Src, typename Dst> Dst convert(Src src)



这两种定义的差别主要在于模版形参,从直觉上看,从src转化到dst,可能第二种定义更符合我们的逻辑,但是第一种定义,更能方便函数模版的调用者—— i = Convert<int>(7.04); ,不需要像这样写完整的模版形参—— i = Convert<int, double>(7.04); ,尽管他们是等价的。

这个例子告诉我,对待别人要宽——让用户更方便的使用。

写到这里,又想起一个例子,跟C++模版没关系:

我们作为开发,在一个类中实现"<"的重载时,也要实现">"和“==”的重载,因为调用者会觉得,既然有了"<"操作,那么“==”和“>”自然也有。

然而,我们作为一个类的使用者时,尽可能少使用重载方法,采用一个"<"就能满足比较操作。这样,即使程序员没有实现所有比较符号的重载,我的代码也能正常运行。

这又是一个对自己要严格,对别人要宽泛的例子。

转载于:https://my.oschina.net/u/1453800/blog/210176

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值