[cpp primer随笔] 04.类型别名与推断

1. 类型别名

为已有的类型设置别名可以在一定程度上提高程序的可阅读性与语义性。

1.1 typedef

typedef是C++关键字之一,同时也是某些基本数据类型的一部分。任何使用typedef作为前缀的基本数据类型,都可以用于定义已有类型的别名。

typedef double cost, *p_cost;

上面的例子中,使用typedef定义了两个类型别名,cost等同于double,而p_cost等同于double*。后者是因为该语句本身是一条定义语句,*p_cost作为声明符存在,故p_cost应当为指向double对象的指针。

1.2 using

在C++ 11及其之后的版本里,可以使用using显示指定类型别名。

using cost = double;
using p_cost = cost*;

1.3 指针类型别名的理解

使用typedefusing语句定义的类型别名,在与const等修饰符结合使用时,应将之视为完整类型,而非简单的进行字符的宏替换。举个例子:

using p_cost = double*;
double count = 10;
const p_cost a = &count; // ok
const double* b = &count; // error

这里ab两个变量是两种不同的类型。前者是一个指针常量,一经初始化变无法改变;而后者则是指向const double类型的常量指针,因此使用非常量类型变量的地址对其进行初始化,会发生编译时错误。

2. 类型推断

2.1. auto类型说明符

auto关键字(C++ 11)可以根据变量的初始值,在编译时推断出其基本数据类型。

auto myInt = 5; // myInt的类型是int
auto p_myInt_1 = &myInt; // p_myInt_1的类型是int*
auto *p_myInt_2 = &myInt; //p_myInt_2的类型是int*

可以看到,auto在变量的定义或声明语句里,用于代替基本类型。
使用auto时,需注意以下几点:

  • 当引用作为初始值时,auto推断的是它所绑定对象的类型。
int a = 10, &b = a;
auto c = b; // c是int,而非int&
  • auto会忽略顶层const,保留底层const,如果需要顶层const特性,需要显示说明。
const int a = 10;
auto b = a; // b是int,而非const int
const int* const c = &a;
auto d = c; // d是const int,也就是说d本身并不是一个常量,顶层const特性被消除掉了
auto const e = c; // 此时e才具备与c相同的特性,即同时有顶层const与底层const特性
// 此时auto const和const auto效果一样,因为auto结果将被const视作完整类型进行修饰
  • 使用auto连续定义多个变量时,auto所推断出来的类型为第一个变量初始值的类型。
auto a = 10, b = &a; // 错误,b的类型应当与a的一致,都为int才行
auto c = 10, *d = &c; // 正确,在声明符里加*或&修饰符是可以的

2.2. decltype类型指示符

auto不同,deletype(C++ 11)根据一个表达式来确认变量的类型,在定义变量时无需初始值。

int sum(int a, int b){
	return a + b;
}
decltype(sum(1, 3)) c; // c的类型为int

编译器只会分析表达式的类型,而不会真正计算表达式的值。
使用decltype时,需注意以下几点:

  • decltype推断可以得到指针、引用、顶层const、底层const。
int a = 10, *b = &a, &c = a; // a是int, b是int*,c是int&
const int d = 10;
const int* const e = &d;

decltype(b) B; // B是int*
decltype(c) C; // C是int&
decltype(e) E; // E是const int* const,同时保留了顶层与底层const
  • 在将变量用作类型推断时,得到该变量类型。但是如果在变量外嵌套一层括号,则该变量会被视作表达式。因为变量是一种可用作赋值表达式左值的特殊表达式,因此对变量表达式的进行类型推断永远会得到引用。
int i = 0;
decltype(i) a; // a的类型为int
decltype((i)) b; // b的类型为int&, 没有进行初始化的引用将引发错误
  • 计算表达式或字面量的类型推断结果并非常量引用,而是它们的基本数据类型。
decltype(5) a = 10; // a和b的类型均为int,而非临时量对象的const int&类型
decltype(a + 1) b = 11;

你可能感兴趣的:(C++,c++)