C++ 11/14之可变参类模板与模板模板参数

可变参类模板

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

组合关系(复合关系):

class B{
public//...
}
class A{
public//...
	 B b,   //A中包含B对象
}
组合关系展开参数包案例
template <typename First, typename... Others>
class myclass<First, Others...>{
	public:
			myclass():m_i(0)
			{
			   printf("s%执行了"this)}
			myclass(First parf, Others... paro):m_i(parf), m_obj(paro ...)
			{
			   printf("s%执行了"this)}
	First m_i;
	myclass m_obj;          //组合关系,参数多的类包含参数少的类

}

myclass<int, float, double>(12, 13.5f, 23);

图
在这里插入图片描述

注意每一个对象地址都不相同

通过tuple和递归调用展开参数包

实现思路:计数器从0开始,每处理一个参数,计数器+1;
一直到把所有参数处理完, 最后一个模板偏特化,作为处理结束。

元组介绍:

tuple<float,int,int> mytuple(13.4f, 52, 10);  //一个元组,一堆东西的组合
cout << get<0>(mytuple) << endl;
cout << get<1>(mytuple) << endl;
cout << get<2>(mytuple) << endl;
通过tuple和递归调用展开参数包案例
//mycount 用于统计,从0开始,mymaxcount表示参数数量
template<int mycount , int mymaxcount, typename...T>
	class myclass
	{
	publicstatic void myfunc(const tuple<T...>&t)
				{
					cout << "value" << get<mycount>(t)< < endl;
					myclass<mycount + 1, mymaxcount, T...>::myfunc(t);  //递归调用
				}
	}
//需要一个特殊版本结束递归调用
template<int mymaxcount, typename...T>
	class myclass<mymaxcount, mymaxcount, T...>
	{
	publicstatic void myfunc(const tuple<T...>&t)
				{
				
				}
	}
template<typename...T>
void testfunc(const tuple<T...>&t)   //可变参数模板
{
	myclass<0, sizeof...(T), T...>::myfunc(t);
}
void func(){
	tuple<float,int,int> mytuple(13.4f, 52, 10);
	testfunc(mytuple);
}

总结

获取参数包的方法有很多种,一般都离不开递归

模板 模板参数

表示这是个 模板参数,这个模板参数本身,又是 一个模板

template<
		typename T;   //类型 模板参数
		typelate<class> class Container;  //模板 模板参数   
       //或者写成typelate<typename W> typename Container	W只是占位,没有用途,可以省略
>
				/*
				typelate<class> 
				class Container
				*/
class myclass{
		T m_i;
		Container<T> myc;                //Container是作为一个类模板来使用的 
		                                 //因为它后面带有<T>,所以是类模板。
		myclass(){
				for(int i = 0; i < 10, ++i){
					myc.pushback(i);      //如果传入的容器不支持pushback会报错
				}
		}
}template<typename T>  using MyVec = vector<T, allocator<T>>;     //这种套路或者写法很固定
template<typename T>  using MyList = list<T, allocator<T>>;      //这种套路或者写法很固定

myclass<int, MyVec>  myvec_obj;   //往容器中塞元素,元素为int
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#include<iostream> using namespace std; class student; class teacher { public: int a = 1; student *p; teacher(int a); ~teacher(); }; teacher::teacher(int a) :a(a) { cout << "teacher构造函数调用" << endl; ///p = new student; } teacher::~teacher() { cout << "teacher析构函数调用" << endl; } class student { public: //友元函数可以访问类中的公有和私有成员,不可以访问保护成员 friend void func2(student &s); friend class teacher; int a = 10; student(int x); ~student(); void func3(); private: int b = 20; }; student::student(int x) :a(x) { cout << "student 构造函数调用1" << endl; } student::~student() { cout << "student 析构函数调用!" << endl; } void student::func3() { cout << b << endl; } void func1() { student s1(100); cout << s1.a << endl; s1.func3(); func2(s1); cout << s1.a << endl; } //友元函数,全局函数做友元 //在形中加入const防止传入的参数被改变,不加const则可以改变 void func2( student &s) { //传入普通类对象不可以改变类中的值,只能改变形类的值 /*s.a = 123; cout<<s.a << endl; cout << s.b << endl;*/ ////传入指针可以改变类的值 /*s->a = 1000; s->b = 123; cout << s->a << endl; cout << s->b << endl;*/ ///传入引用也可以改变类中的值 //s.a = 12345; //s.b = 123456; cout << s.a << endl; cout << s.b << endl; } //类做友元 void func3() { student s1(10); cout << s1.a << endl; teacher t1(100); cout << t1.a << endl; cout << t1.p->a<< endl; } int main() { //成员函数做友元 //func1(); //类做友元 func3(); system("pause"); return 0; }
最新发布
06-08

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值