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

戏子无情 提交于 2020-05-04 02:17:35
偏特化就是部分特化。
利用模版的偏特化,可以实现一些类型过滤。
比如,我想让一个类模版指定类型如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++模版没关系:

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

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

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!