1. 定义别名方法
(1)typedef
typedef double wages; //wages是double的同义词
typedef wages base, *p; // base是double的同义词,p是double*的同义词
typedef和函数指针
typedef char (*PTRFUN)(int); //相当于定义了一种新的类型,这里的PTRFUN
是一个函数指针类型,其参数为int型,返回值为char类型
PTRFUN pFun; //定义了一个函数指针
char glFun(int a){ return;} //函数声明
void main()
{
pFun = glFun; //函数指针初始化
(*pFun)(2);
}
注意:当const和typedef一起出现时,typedef不会是简单的字符串替换。typedef是定义了新的类型,不是简单地别名替换
typedef char* pstring;
const pstring cstr = 0;
const pstring *ps;
这里如果是别名替换,就是const char *,即cstr是指向const char的指针,而
实际上这里的cstr是一个指向char的常量指针,即char * const;
(2)using:别名声明,用于替代typedef的作用,可读性更好
c++11新出现,using SI = sales_item;
另外在定义模板别名时,用typedef会报错,而使用using就不会,所以官方是更推荐使用using
(3)typename:主要用在模板中
template<typename T>
int compare(T &a, T &b){};
typename在下面情况下禁止使用:
- 模板定义之外,即typename只能用于模板的定义中
- 非限定类型,比如前面介绍过的int,vector之类
- 基类列表中,比如template class C1 : T::InnerType不能在T::InnerType前面加typename
- 构造函数的初始化列表中
- 如果类型是依赖于模板参数的限定名,那么在它之前必须加typename(除非是基类列表,或者在类的初始化成员列表中)
- 其它情况下typename是可选的,也就是说对于一个不是依赖名的限定名,该名称是可选的,例如vector vi;
2. decltype:c++11引入,用于选择并返回操作数的数据类型
decltype(f()) x = a; //x的类型就是函数f()的返回类型`
const int ci = 0, &cj = ci;
decltype(ci) x = 0; //x的类型是const int
decltype(cj) y = x; //y的类型是const int&
decltype(cj) z;//error, z需要初始化
decltype和引用:如果decltype使用的表达式不是一个变量,则decltype返回表达式结果对应的类型
int i = 42, *p = &i, &r = i;
decltype(r) b = i; //这里b类型就是int&
decltype(r + 0) c = i; //这里使用的是一个表达式,表达式的结果类型就是
int,所以c的类型就是int
decltype(*p) d = i; //这里的*p是引用,所以d也是引用,必须初始化
除此之外:decltype((i)) d;//error,这里的d一定是引用,必须初始化
decltype(i) e; //这里的e是不是引用需要看i本身是不是引用