C++10:非类型模板参数以及模板的特化

目录

非类型模板参数

模板的特化

模板类的特化

 1.全特化

2.偏特化


模板其实还有其他的玩法,比如非类型模板参数以及模板的特化。

非类型模板参数

在记述非类型模板参数前,我们认识一下C++中一个比较鸡肋的类,array

#include<iostream>
#include<array>
using namespace std;

int main()
{
    array<int, 10>a1;

    cout << a1[5] << endl;
}

  • 相较于C语言宽松的数组越界检查,array则可以直接在越界访问时报错。但用习惯了原生数组,换成用这个格式繁琐的数组,有点得不偿失,毕竟越界还是跟我们写逻辑的人有关。
  • 但是这个东西里面的显示实例化里头有一项比较惹人注意,这个是什么?

 这个就是非类型模板参数了,不同于我们之前使用的模板参数只能传递类型,在这里,它允许我们传递一个整型。

namespace bite
{
    // 定义一个模板类型的静态数组
    template<class T, size_t N = 10>
    class array
    {

    public:
        T& operator[](size_t index) { return _array[index]; }    

        const T& operator[](size_t index)const { return _array[index]; }
        size_t size()const { return _size; }
        bool empty()const { return 0 == _size; }
    private:
        T _array[N];
        size_t _size;
    };
}
  • 反正就是定义了一个模板参数,但是这个模板参数并不是泛型,而是指定类型,在当前的这个模板下,我们可以把这个非类型模板参数当成正常的参数使用。
  • 但是这个非类型模板参数只适合整型常量,什么意思呢?

一个非类型模板参数,它不能接收除了整型之外的类型,不然就报错,而且必须是常量,变量也不行。

 型变量主要还是应对需要传递整型参数来控制值的情况,还是有用的。

模板的特化

  • 有时候我们希望我们写下的泛型代码在某些特殊的情况下能特殊处理。
  • 说明白一点就是传入什么东西就照着对应的方法进行处理,好比一家洗衣店,普通的衣物直接水洗,特殊的衣物换成干洗。
  • 套用至代码范畴,我们希望传递参数的时候传入变量的时候对比其大小,传入指针时解引用再比较。
  • 大体情况来形容就是特殊通道,比如高铁站的特殊人群快速通道
template <class T>
bool Little (const T& x, const T& y)
{
    return x < y;
}

int main()
{
    //传整型
    int a = 10, b = 20;
    cout << Little(a, b) << endl;

    //传地址
    int* pa = &a, * pb = &b;
    cout << Little(pa, pb) << endl;

}

  •  在这种情况下我们的函数模只是比对了两个地址的大小,而我们的本意希望他可以比较地址指向的值的大小,这个时候我们就可以用模板特化来让这个模板函数如我们所愿。
template <class T>
bool Little ( T x, T y)
{
    return x < y;
}

//模板特化
template <>
bool Little<int*>( int* x, int*  y)
{
    return *x < *y;
}

但是想要成功特化,传递参数的修饰符需要是一样的,比如说我的原生函数模板用的是引用接收传参,那么我的特化也是要变成引用

 当然由于C++支持函数重载,换成重载方式去写也是完全没问题的。

 但毕竟只有函数能重载,要是类模板的话就不行了,类只能乖乖的用特化来实现。

模板类的特化

 1.全特化

template<class T1, class T2>
class Text
{
public:
	Text()
	{
		cout << "使用的是<int , int>类型" << endl;
	}
private:
	T1 _data1;
	T2 _data2;

};

//全特化
template<>
class Text<double, double>
{
public:
	Text()
	{
		cout << "使用的是<double , double>类型" << endl;
	}
private:
	double _data1;
	double _data2;

};

2.偏特化

//偏特化
template<class T>
class Text<T, double>
{
public:
	Text()
	{
		cout << "使用的是<T , double>类型" << endl;
	}
private:
	T _data1;
	double _data2;

};

 以上就是大致的特化使用举例描述了。

 当笔记用

猜你喜欢

转载自blog.csdn.net/m0_53607711/article/details/129224017