数组模板和模板参数

类型参数

泛型名称声明:

template<typename T>

上述T是一泛型名称,也是通过typename指明的类型参数,string,int作为具体的类型传入进去,非类型参数就是在模板中加入常规类型变量int n,n本身指的就是int型,不是用作泛型,就是非类型参数.

可设定大小容器类实现

模板通常用于容器类,容器类的大小可以自我设定有两种方法:

  1. 通过动态分配和构造函数参数,但是,这样比较麻烦,因为,在类中进行动态分配,要考虑到赋值运算符,复制构造函数的重写.

  2. 通过在模板上的参数添加非类型参数,指明数组大小,这样就更加方便,不用重写很多函数了

重新用非类型参数和数组完成一个简单类设计

template <typename T, int n>
	class ArrayTP
	{
	private:
	    T ar[n];		// T为类型参数,n为非类型参数
	public:
	    ArrayTP() {};
	    explicit ArrayTP(const T & v);		// 防止T类型隐式转换
	    virtual T & operator[](int i);		// 可以被赋值并改变数组中某个值的方法,用作左值
	    virtual T operator[](int i) const;		// const不允许改变,而是返回一个值的副本,可以拿来进行赋值.
	};

	template <class T, int n>
	ArrayTP<T,n>::ArrayTP(const T & v)
	{
	    for (int i = 0; i < n; i++)
		ar[i] = v;
	}

	template <class T, int n>
	T & ArrayTP<T,n>::operator[](int i)
	{
	    if (i < 0 || i >= n)
	    {
		std::cerr << "Error in array limits: " << i
		    << " is out of range\n";
		std::exit(EXIT_FAILURE);
	    }
	    return ar[i];
	}

	template <class T, int n>
	T ArrayTP<T,n>::operator[](int i) const
	{
	    if (i < 0 || i >= n)
	    {
		std::cerr << "Error in array limits: " << i
		    << " is out of range\n";
		std::exit(EXIT_FAILURE);
	    }
	    return ar[i];
	}

非类型参数的限制:整形,枚举,引用,指针.所以double m是不合法的.上面的模板中,n不能能进行改变,所以n++和&n的等表达式不能用.而且非类型参数必须使用常量.

  1. 递归使用模板

模板可以自己作为一个类型参数调入.

ArratTP< ArrayTP<int , 5>,10 >  twodee;

这句话的意思就是,twodee是一个的模板类的对象,存储十个元素,每个元素又是一个ArrayTP<int,5>类型的对象,ArrayTP<int ,5>对象存储的又是5个int型的整形,所以这个相当于二维数组的int twodee[10][5].

测试函数如下:

int main(void)
	{
	    using std::cout;
	    using std::endl;
	    ArrayTP<int, 10> sums;
	    ArrayTP<double, 10> aves;
	    ArrayTP< ArrayTP<int,5>, 10> twodee;
	  
	    int i, j;
	    
	    for (i = 0; i < 10; i++)
	    {
		sums[i] = 0;
		for (j = 0; j < 5; j++)
		{
		    twodee[i][j] = (i + 1) * (j + 1);
		    sums[i] += twodee[i][j];
		}
		aves[i] = (double) sums[i] / 10;
	    }
	    for (i = 0; i < 10; i++)
	    {
		for (j = 0; j < 5; j++)
		{
		    cout.width(2);
		    cout << twodee[i][j] << ' ';
		}
		cout << ": sum = ";
		cout.width(3);
		cout  << sums[i] << ", average = " << aves[i] << endl;
	    }
	    
	    cout << "Done.\n";
	    return 0;
	}

测试结果如下:

在这里插入图片描述

  1. 模板还可以用多个类型参数,比如template <typename T1,typename T2>.

有的时候希望类可以保存两种值,设计如下:

template <typename  T1, typename  T2>
	class Pair
	{
	private:
	    T1 a;
	    T2 b;
	public:
	    T1 & first();
	    T2 & second();
	    T1 first() const { return a; }
	    T2 second() const { return b; }
	    Pair(const T1 & aval, const T2 & bval) : a(aval), b(bval) { }
	    Pair() {}
	};

	template<class T1, class T2>
	T1 & Pair<T1,T2>::first()
	{
	    return a;
	}
	template<class T1, class T2>
	T2 & Pair<T1,T2>::second()
	{
	    return b;
	}

测试函数如下:

i
nt main()
	{
	    using std::cout;
	    using std::endl;
	    using std::string;
	    Pair<string, int> ratings[4] =
	    {
		Pair<string, int>("The Purpled Duck", 5),
		Pair<string, int>("Jaquie's Frisco Al Fresco", 4),
		Pair<string, int>("Cafe Souffle", 5),
		Pair<string, int>("Bertie's Eats", 3)
	    };

	    int joints = sizeof(ratings) / sizeof (Pair<string, int>);
	    cout << "Rating:\t Eatery\n";
	    for (int i = 0; i < joints; i++)
		cout << ratings[i].second() << ":\t "
		     << ratings[i].first() << endl;
	    cout << "Oops! Revised rating:\n";
	    ratings[3].first() = "Bertie's Fab Eats";
	    ratings[3].second() = 6;
	    cout << ratings[3].second() << ":\t "
		 << ratings[3].first() << endl;
	   return 0; 
	}

测试结果如下:

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值