处理类型


类型别名

两种方法定义类型别名:

  • 传统的关键字 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& 类型必须初始化