类型别名
两种方法定义类型别名:
- 传统的关键字
typedef
。 - 新标准规定的
using
。
typedef double wage;
using wage = double;
auto 类型说明符
- C++11新标准引入的
auto
类型说明符,用它可以让编译器替我们分析表达式所属的类型。 auto
让编译器通过初值来推算变量的类型,显然,auto
定义的变量是必须有初值的。auto
也可以在一条语句中声明多个变量,但是这些变量的初始基本数据类型必须相同。
auto i = 0,*p =&i; //正确,i是int,p是int*
auto sz = 0,pi = 3.14; //错误,基本数据类型不一致
复合类型、常量和auto
使用引用其实是使用引用的对象,所以当引用被用作初始化auto变量时,实际上参与初始化的是引用绑定的对象。
int i = 0,&r = i;
auto a = r; //a是一个int类型,而不是一个int&类型
auto
会忽略掉顶层 const
,底层 const
会被保留。
const int ci = i,&cr = ci;
auto b = ci; //b是一个int类型
auto c = cr; //c是一个int类型
auto d = &i; //d是一个int*类型
auto e = &ci; //e是一个const int*类型
如果需要 auto
推断出的是顶层 const
,则需要显示指明:
const auto f = ci; //f是一个const int
还可以将引用的类型设置为 auto
,设置一个类型为 auto
引用时,顶层的 const
属性仍然保留。
auto &g = ci; //g是const int&
decltype 类型指示符
C++11 第二种类型说明符 decltype
,它的作用是选择并返回操作数的数据类型,在此过程中,编译器分析表达式并得到类型,但不实际计算它的值。
decltype(f()) sum = x;//sum的类型就是f的返回类型
decltype
处理顶层 const
和引用的方式与 auto
不相同,如果 decltype
使用的表达式是一个变量,它将返回这个变量实际的类型(包含顶层 const
和引用)。
const int ci = 0,&cj = ci;
decltype(ci) x = 0; //x是const int类型
decltype(cj) y = x; //y是const int&类型
需要注意的是,引用从来都作为其所指向对象的同义词出现,只有用在 decltype
处是一个例外。
decltype 和引用
如果 decltype
使用的是表达式而不是一个变量,则 decltype
返回表达式的结果对应的类型。
int i = 42,*p = &i,&r =i;
decltype(r+0) b; //正确,b是一个int类型
decltype(*p) c; //错误,c是int&类型,必须初始化
decltype(r)
的结果是引用类型,而 r+0
是一个具体的值,并非是引用。
如果表达式是解引用操作,则 decltype
将得到引用类型,decltype( *p)
得到的是 int&
,而不是 int
。
另外需要特别注意的是,对于decltype使用的表达式来说,如果变量名加上一对括号,则得到的类型和不加括号时会有不同:
- 如果decltype使用的是一个不加括号的变量,则得到的结果是该变量类型。
- 如果给变量加上一层或者多层括号,编译器就会把它当成一个表达式,结果将是引用类型。
int i = 42;
decltype(i) d; //正确,d是int类型
decltype((i)) e; //错误,e是int& 类型必须初始化