【模板参数】模板模板参数

一、模板模板参数的使用

模板模板参数的英文为 T e m p l a t e   T e m p l a t e   P a r a m e t e r s Template \ Template \ Parameters Template Template Parameters,实际上就是使用模板参数本身成为模板。
我们看下面的例子:
如果我们要实现一个自定义容器,以 s t d : : v e t c o r std::vetcor std::vetcor作为默认容器类型,那么我们可能会写出以下代码:

template<typename T,typename Container = std::vector>
class mylist {
private:
	Container<T>myli;
};

但是这样的代码不能通过编译,因为我们传入的 C o n t a i n e r Container Container是一个类模板容器,编译器不能识别出来,因此我们需要使用到模板模板参数,如下所示:


//template<typename T,template<typename > typename Container = std::vector>

//使用class也可以
template<typename T, template<class> class Container = std::vector>
class myvector {
private:
	Container<T> myvec;
public:
	myvector() {
		std::cout << "调用了myvector的构造函数\n";
	};

	//....//
};

随着 C + + C++ C++新标准的不断引入,可以使用 t y p e n a m e typename typename逐渐替代 c l a s s class class了。
因此下面两种形式都是可以的:

t e m p l a t e < t y p e n a m e   T , t e m p l a t e < t y p e n a m e > t y p e n a m e   C o n t a i n e r template<typename \ T,template<typename > typename \ Container template<typename T,template<typename>typename Container
t e m p l a t e < t y p e n a m e   T , t e m p l a t e < c l a s s > c l a s s   C o n t a i n e r = s t d : : v e c t o r > template<typename \ T, template<class> class \ Container = std::vector> template<typename T,template<class>class Container=std::vector>

对于不使用的模板参数名称,也可以省略。通常,嵌套内层的参数是用不到的,可以省略名称:

//省略名称
//如果有的名称没有被使用,则可以不需要写出来。
template<typename, template<typename>typename = std::vector>
class myvector3 {
	
	//不使用名称

	//...//
};

注意的是,内层嵌套的模板参数名称,不能被外层的类模板所使用,如:

//嵌套的模板定义的参数不能被外层使用
template<typename T,template<typename U>typename Container = std::vector>
class myvector2 {
private:
	Container<T>myvec;

public:
	
	//U my_vari; //无法使用U类型,因为在嵌套内的参数列表
	
};

因为 U U U类型实在嵌套模板内的,所以这里类内无法使用 U U U类型。

二、成员函数的实现

对于成员函数,在类内实现很简单,直接实现即可:

emplate<typename T, template<typename>typename Container= std::vector >
class myvector4{
private:
	Container<T> myvec;

public:
	
	myvector4() {};

	myvector4(size_t n, T val = {}) {
		myvec.resize(n, val);
	}
	
	//类内实现成员函数
	void push_back(T const& val) {
		myvec.push_back(std::move(val));
	}

	void print();
};

我们尝试在类外实现一下 p r i n t print print函数,如下:

//类外实现成员函数

//类外不能指定参数,因为一开始实例化的时候已经指定过了
template<typename T, template<typename>typename Container /* = std::vector*/ > 
void myvector4<T, Container>::print() {
	for (auto const& val : myvec) {
		std::cout << val << " ";
	}
	std::cout << std::endl;
}

注意在类外声明参数的时候不要使用默认参数,因为成员函数只有在调用时才会实例化,而参数类型在创建类的时候就被实例化了,所以不能指定。

运行一下:

void Test2() {
	myvector4<std::string>myvec;
	
	myvec.push_back("hello");
	myvec.push_back("world");
	myvec.push_back("!");

	myvec.print();
}

成功调用了了成员函数:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值