C++ 模板 class,typename的区别 tcy

1.1.定义:模板是泛型编程的基础,泛型编程即以一种独立于任何特定类型的方式编写代码。
          typename标识嵌套从属类型名称, 但不需在基类列表和成员初始化列表内使用. 
1.2.分类:
1)从属名称: 模板(template)内出现的名称, 相依于某个模板(template)参数, 如T t;
2)嵌套从属名称:从属名称在class内呈嵌套装, 如T::const_iterator ci;
3)非从属名称 : 不依赖任何template参数的名称, 如int value; 
1.3.class,typename的区别:
1)在声明模板参数时,class和typename可互换
2)嵌套依赖类型名:必用typename去标识嵌套依赖类型名;(不能用class)
  格式:typename 嵌套依赖类型名;
  例外:基类标识符在基类列表中或在成员初始化列表中省略typename;
实例1.1:模板参数-函数
template <typename T1, class T2> 
inline const T1 max(const T1 &x, const T2 &y)
{T1 z = T1(y); return (x < z)? z : x;}

inline const int Max(const int &x, const float &y)
{int z = int(y); return (x < z)? z : x;}

int main(){
 size_t x = 6; float y = 8;
 cout << max(x, y) << endl;//8
 cout << Max(x, y) << endl;//8
}
实例1.2:模板参数-类
template<class T1, typename T2>
class A {
private:
	T1 x;
	T2 y;
public:
	A(T1 x = 0, T2 y = 0);
	A add(const A<T1, T2> &a)const;
	void show()const;
};

template<class T1, typename T2>
A<T1, T2>::A(T1 x, T2 y) :x(x), y(y) {}

template<class T1, typename T2>
A<T1, T2> A<T1, T2>::add(const A<T1, T2> &a)const
{return A<T1, T2>(x + a.x, y + a.y);}

template<class T1, typename T2>
void A<T1, T2>::show()const { cout << "[" << x << "," << y << "]" << endl; }

int main() {
	A<int,double> x(1, 2.2), y(2, 3.3), z;
	z = x.add(y);
	z.show();  //[3,5.5]
}

 

实例2.1:嵌套依赖类型:内部成员的嵌套依赖
struct STRUCT_INT_TYPE{typedef int INT_TYPE;};

template <typename T>
void foo(const T& t){
	/*
	声明类型为T::INT_TYPE对象的指针
	typename说明T::INT_TYPE是一个类型名而不是变量名
	注意:
	任何含有名为“INT_TYPE”项的类T,都可被当作模板参数传入foo()函数,包括typedef类型、枚举类型或变量等
	*/
	typename T::INT_TYPE * p;
	
	//T::INT_TYPE * p;//错误
	//编译器默认INT_TYPE为变量名,而非类型名;
	//T::INT_TYPE * p 其中“*”被解释为乘法;结果为INT_TYPE(变量)*p(变量)
	
	int x = 10;
	p = &x;
	printf("p=%p;*p=%d", p, *p);//p=000000499C9FFB54;*p=10
}

int main(){
	STRUCT_INT_TYPE int_type ;
	foo(int_type);
}
实例2.2: 嵌套从属类型名称, 如果是基类列表和成员初值列中, 不使用typename; 
#include <iostream>
#include <vector> 
using namespace std;

struct STRUCT_TYPE {
	STRUCT_TYPE(int x) { cout << "x=" << x << endl; } 
};

template<typename T>                                //必须添加
struct Base { typedef STRUCT_TYPE STRUCT_OBJ; };

template<typename T>
class A : public Base<T>::STRUCT_OBJ {              //不用typename
public:
	explicit A(int x) : Base<T>::STRUCT_OBJ(x) {    //不用typename
		typename Base<T>::STRUCT_OBJ temp(7);       //必须使用
	}
};

int main() { 
	A<int> d(5); 
}

输出:
Number = 5
Number = 7 
实例3:当使用特性类(traits class)时, 必须使用typename, 如 
template<typename T>
void func(T iter)
{
	typedef typename std::iterator_traits<T>::value_type value_type; //使用typename
	
	value_type temp(*iter); 
	cout << "temp = " << temp << endl;
}
int main() {
	std::array<int, 5> arr = { 1,2,3,4,5 };
	std::array<int, 5>::iterator iter = arr.begin()+2;
	func(iter);
}
输出:temp = 1
实例4:vector模板类
#include <stdio.h>
#include <string>
#include <iostream>
#include <vector>
using namespace std;
#define TEMPLATE_TYPE_T1_T2  template <typename T1, class T2>

TEMPLATE_TYPE_T1_T2
class Array {
private:
	T1 len;
	vector<T2> vec;
public:
	Array() {}
	Array(T1 len);
	Array(const Array &b);
	Array(const T2*p, T1 len); //vector<int> val{ vector<int>(5,0) };
	void operator=(const Array &a);
	~Array() {};
	T1 get_len(void);
	void set_len(T1 len);
	void resize(const T1 len, T2 val = T2(0));//只能在声明(非定义)中定义默认参数
	void view();
};
TEMPLATE_TYPE_T1_T2
Array<T1,T2>::Array(T1 len) { this->len = len; vec.resize(len, T2(0)); }

TEMPLATE_TYPE_T1_T2
Array<T1, T2>::Array(const Array &b) { len = b.len; vec = b.vec; }

TEMPLATE_TYPE_T1_T2
Array<T1, T2>::Array(const T2*p, T1 len) { this->len = len; vector<T2> vec1(p, p + len); vec = vec1; }

TEMPLATE_TYPE_T1_T2
void Array<T1, T2>::operator=(const Array &a) { len = a.len; vec = a.vec; }

TEMPLATE_TYPE_T1_T2
T1 Array<T1, T2>::get_len(void) { return len; }

TEMPLATE_TYPE_T1_T2
void Array<T1, T2>::set_len(T1 len) { this->len = len; resize(len); }

TEMPLATE_TYPE_T1_T2
void Array<T1, T2>::resize(const T1 len, T2 val) { vec.resize(len, val); }//不允许使用默认参数

TEMPLATE_TYPE_T1_T2
void Array<T1, T2>::view()
{
	cout << "{\"len\":" << vec.size() << ",\"vec\":[";
	for (T1 i = 0; i < vec.size(); i++) cout << vec.at(i) << ",";
	cout << "]}" << endl;
}

class ARRAY {
private:
	size_t len;
	vector<float> vec;              
public:
	ARRAY() {}
	ARRAY(size_t len);
	ARRAY(const ARRAY &b);
	ARRAY(const float*p, size_t len); //vector<int> val{ vector<int>(5,0) };
	void operator=(const ARRAY &a);
	~ARRAY() {};
	size_t get_len(void);
	void set_len(size_t len);
	void resize(const size_t len,float val = float(0));//只能在声明(非定义)中定义默认参数
	void view();
	};
ARRAY::ARRAY(size_t len) { this->len = len; vec.resize(len, float(0)); }
ARRAY::ARRAY(const ARRAY &b) { len = b.len; vec = b.vec; }
ARRAY::ARRAY(const float*p, size_t len){this->len = len; vector<float> vec1(p, p + len); vec = vec1;}

void ARRAY::operator=(const ARRAY &a) { len = a.len; vec = a.vec; }
size_t ARRAY::get_len(void) { return len; }
void ARRAY::set_len(size_t len) { this->len = len; resize(len); }		
void ARRAY::resize(const size_t len, float val ) { vec.resize(len, val); }//不允许使用默认参数
	
void ARRAY::view() 
{
	cout <<"{\"len\":"<< vec.size() << ",\"vec\":[";
	for (size_t i = 0; i < vec.size(); i++) cout << vec.at(i) << ",";
	cout << "]}" << endl;
}
int main(){  
	//测试类
	Array<size_t,float> a1,a2(x),a3(a2),a4(arr1,4);
	a1.view(); a2.view(); a3.view(); a4.view();
	a1 = a4; a2 = a4; a3 = a4;
	a1.view(); a2.view(); a3.view(); a4.view();
	a4.resize(6);
	a4.view();
	return 0;
}
/*
{"len":0, "vec" : []}
{"len":6, "vec" : [0, 0, 0, 0, 0, 0, ]}
{"len":6, "vec" : [0, 0, 0, 0, 0, 0, ]}
{"len":4, "vec" : [1, 2, 3, 4, ]}
{"len":4, "vec" : [1, 2, 3, 4, ]}
{"len":4, "vec" : [1, 2, 3, 4, ]}
{"len":4, "vec" : [1, 2, 3, 4, ]}
{"len":4, "vec" : [1, 2, 3, 4, ]}
{"len":6, "vec" : [1,2,3,4,0,0,]}
*/

 

 

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值