可变参模板[varidic template],包括可变参函数模板和可变参类模板
template
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 m1; myclass m2; myclass 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(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
//templateclass 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;
}