【类模板】类模板的模板参数

一、类模板的参数

1.默认参数

类模板的参数可以有默认值。但是指定默认值必须让有默认值的参数都放在最后。
下面是一个带有默认值的类模板:

//默认参数
template<typename T = char, typename U = int>
struct TC {
	T val_1;
	U val_2;

	TC(T val1__, U val2__) :val_1(val1__), val_2(val2__) {}
};


由于模板有默认值,所以我们可以实例化模板的时候选择就更多了:

void Test1() {
	TC<> t1('a', 1); //使用默认参数

	TC<double> t2(1.0, 1);//第一个使用自定义参数,第二个使用默认参数

	TC<double, float>t3(1.0, 1.0);//两个都使用自定义参数

}

2. 有依赖的默认参数

有时候,类模板的参数会依赖于之前的参数,比如指针(*),引用(&)等:

//有依赖的默认参数
template<typename T,typename U = T*> //U为T的指针
struct TC_ {
	T val_1;
	U val_2;

	TC_(T val1__, U val2__) :val_1(val1__), val_2(val2__) {}
};

实例化时,传入两个参数分别表示值和指针。

void Test2() {
	int x = 1;
	int* ptr = nullptr;
	TC_<int>t(x, ptr); 
}

3.类模板声明默认参数

我们可以在类模板的声明就设置默认参数,这样我们在定义类模板的时候就不需要设置默认参数了。

声明可以是多次的,如下所示:

//在模板声明中指定默认参数

//类模板声明
template<typename T,typename U,typename V = int,typename W = char>
struct _TC;

//继续声明指定默认参数,之前声明过的默认参数不需要再次声明
template<typename T, typename U = char, typename V, typename W> 
struct _TC;

//类模板定义
template<typename T, typename U, typename V , typename W > 
struct _TC {
	T val_1;
	U val_2;

	_TC(T val1__, U val2__) :val_1(val1__), val_2(val2__) {}
};

二、类型别名

C + + 11 C++11 C++11之前,我们使用 t y p e d e f typedef typedef对类型取别名,而 C + + 11 C++11 C++11引入了 u s i n g using using关键字,因此有以下两种方法:

//类型别名
typedef TC<int, float>IF_TC;
using ID_TC = TC<int, double>;

使用起来就是这样:

void Test3() {
	IF_TC t1(0,0.0);//相当于TC<int,float>

	ID_TC t2(1, 1.0); //相当于TC<int,double>
}

三、非类型模板参数

类模板的非类型模板参数和函数模板的非类型模板参数类似。
链接:参数类型

这里补充几点:

1.使用 s i z e _ t size\_t size_t来作为非类型模板参数

这里实现了一个数组类模板,传入参数,生成常量 s i z e _ t size\_t size_t个相同的元素:

//非类型模板参数
template<typename T,typename U = T ,size_t arrsize = 8>
struct TC__ {
	T m_arr[arrsize];
	U val;
	
	//初始化arrsize大小的类型为T的数组,每个值为U类型数值
	TC__(U _val):val(_val) {
		for (int i = 0; i < arrsize; ++i) {
			m_arr[i] = val;
		}
	}

	//输出
	void print();
	
};

因为 s i z e _ t size\_t size_t是编译是就确定的常量,所以可以作为非类型模板参数。

注意这里在类外实现的时候,传入的参数:

//类外实现
template<typename T,typename U,size_t arrsize>
void TC__<T, U, arrsize>::print() { //注意这里是arrsize不是size_t
	for (int i = 0; i < arrsize; ++i) {
		std::cout << m_arr[i] << " ";
	}
	std::cout << "\n";
}

注意传入的 a r r s i z arrsiz arrsiz,而不是 s i z e _ t size\_t size_t

2. 全局字符串常量数组作为非类型模板参数

因为字符串常量数组可以在编译时就可以确认了,所以可以作为参数:

template<const char* p>
struct _TC_ {
	_TC_() {
		std::cout << "_TC_的构造函数:p =" << p << "\n";
	}
};
const char* ptr = "hello";

const char p[] = "world";
void Test5() {
	
	//全局指针不能作为模板参数
	//_TC_<ptr> t;
	
	//全局字符串数组可以
	_TC_<p> t; 

	//字符串常量也不行
	//_TC_<"hello">t;

}

注意这里的全局指针和字符串常量都不能作为非类型参数传入,因为他们在编译时无法被直接确认,更多细节如下:
在这里插入图片描述
正如上面所说,在C++20及以上的版本已经可以支持 d o u b l e double double f l o a t float float类型作为非类型模板参数了,而字符串还不可以,期待字符串的引入!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值