C++学习第十

可变参模板[varidic template],包括可变参函数模板和可变参类模板
template<class T,class U> //T,U叫模板参数,因为前面有typename,所以又称【类型模板参数】;
class A{ };

1)可变参函数模板专业术语说明

说明:
1)【T】叫可变参类型,是一包类型;
2) Args叫可变参形参,是一包形参;
总结就是一包类型,一包形参;

template<typename... T> //T是一包类型,可不是一个类型!!!(因为有多个不同类型,所以是typename...)
void func(T... Args) //Args是一包形参(不同类型数据)
{
    
    
    cout << sizeof...(Args) << endl;
    cout << sizeof...(T) << endl;
}

2)参数包的展开案例

template <typename T>
void printValue(const T& t) //递归终止函数
{
    
    
	cout << t << ",";//最后一个元素
}

template <typename T, typename... Args>
void printValue(const T& t, const Args&... args)
{
    
    
	cout << t << ",";
	printValue(args...);
}

int main()
{
    
    
	printValue("hello", "wolrd", "!"); //hello给第一个参数,后面的给args;
}

3)可变参类模板

using namespace std;
//通过递归继承方式展开参数包

template<typename... Args>
class myclass{
    
     }; //主模板

template<typename first,typename... others>
class myclass<first, others...> :private myclass<others...>
{
    
    
public:
	myclass() : m_(0)
	{
    
    
		printf("myclass::myclass()执行了,this is: %p\r\n", this);
	}
	first m_;
};
int main()
{
    
    
	myclass<int, float, double> m1;
	return 0;
}

//输出结果,会生成三个类 myclass<double> m1; myclass<float,double> m2; myclass<int, float, double> m3;
//上面的三个类是继承关系:m3继承m2; m2继承m1;
//myclass::myclass()执行了,this is : 00B5FC34
//myclass::myclass()执行了,this is : 00B5FC34
//myclass::myclass()执行了,this is : 00B5FC34

3.1)调用有参构造函数的可变参类模板






//可变参类模板
//通过递归继承方式展开参数包
template<typename... Args>
class myclass{
    
     }; //主模板

template<> class myclass<>
{
    
    
public:
	myclass() {
    
     printf("myclass<>::myclass()执行了,this is: %p\r\n", this); }
};

template<typename first,typename... others>
class myclass<first, others...> :private myclass<others...>
{
    
    
public:
	myclass() : m_(0)
	{
    
    
		printf("myclass::myclass()执行了,this is: %p\r\n", this);
	}
	myclass(first parf, others... package) :m_(parf), myclass<others...>(package...) //myclass<others...>(package...) 初始化父类
	{
    
    
		cout << "---------------begin---------------" << endl;
		printf("myclass::myclass(parf,package)执行了,this is: %p\r\n", this);
		cout << "m_ : " << m_ << endl;
		cout << "---------------end---------------" << endl;
	}
	first m_;
};
int main()
{
    
    
	myclass<int, float, double> m1(3,4.65,23.98);
	return 0;
}

4)通过递归组合方式展开参数包



using namespace std;
//可变参类模板
//通过递归继承方式展开参数包

template<typename... Args>
class myclass{
    
     }; //主模板

template<> class myclass<>
{
    
    
public:
	myclass() {
    
     printf("myclass<>::myclass()执行了,this is: %p\r\n", this); }
};

template<typename first,typename... others>
class myclass<first, others...>
{
    
    
public:
	myclass() : m_(0)
	{
    
    
		printf("myclass::myclass()执行了,this is: %p\r\n", this);
	}
	myclass(first parf, others... package) :m_(parf),mparent(package...)
	{
    
    
		cout << "---------------begin---------------" << endl;
		printf("myclass::myclass(parf,package)执行了,this is: %p\r\n", this);
		cout << "m_ : " << m_ << endl;
		cout << "---------------end---------------" << endl;
	}
	first m_;
	myclass<others...> mparent;
};
int main()
{
    
    
	myclass<int, float, double> m1(3,4.65,23.98);
	return 0;
}

5)模板模板参数定义方法:



template<typename T> using Myvec = vector<T, allocator<T>>;
template<typename T> using Mylist = list<T, allocator<T>>;

template<class T, template<typename W> class container> //W屁用没有,可以省略 写法1
//template<class T,template<class>class container>  //模板模板参数写法2
class A
{
    
    
public:
	T m_;
	container<T> myContainer;
	A()
	{
    
    
		for (int i = 0; i < 10; i++)
			myContainer.push_back(i);
	}
};
int main()
{
    
    
	A<int,Myvec> myvecobj; //构造函数初始化时,把数据插入到vector容器中
	A<int, Mylist> mylistobj;//构造函数初始化时,把数据插入到list容器中
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_30143193/article/details/132467224