typedef double wages; //wages是double的同义词
typedef wages baser , *p; //base是double的同义词,p是double的同义词
using SI = Sales_item; //SI是Sales_item的同义词
类型别名和类型的名字等价,只要是类型的名字能出现的地方,就能使用类型别名。
auto类型可以根据初始值自动判断类型(有编译器帮助我们判断),因此使用auto 类型时必须要有初始值。
如:
auto i = 10 +100; //i 为int型
auto item = val1 + val2; //如果val是double,则item为double
使用auto也能在一条语句中声明多个变量。因为一条声明语句只能有一个基本数据
类型,所以该语句中所有变量的初始基本数据类型都必须一样:
auto i = 0, *p = &i; //正确:是整数、p是整型指针
auto sz = 0, pi = 3.14; //错误:sz和pi的类型不一致
编译器推断的auto类型有时候和初始值的类型并不完全一样,编译器会适当地改变结构类型使其更符合出事化规则。如:
const auto f = ci; //ci的推演类型是int,f是const int。
#include
using namespace std;
int main()
{
int i = 0, & r = i;
auto a = r; //a是整数(r是i的别名,而i是一个整数)
const int ci = i, & cr = ci;
auto b = ci; //b是整数(ci的顶层const特性被忽略掉了)
auto c = cr; //c是整数(cr是ci的别名,ci本身是一个顶层const)
auto d = &i; //d是整型指针(整数的地址就是指向整数的指针)
auto e = &ci; //e是一个指向整数常量的指针(对常量对象取地址是一种底层const)
const auto f = ci; //f是常量const int
auto& g = ci; //g是整型常量引用,绑定到ci
//auto& h = 42; //错误,不能为非常量引用绑定字面值
const auto& j = 42; //正确,可以为常量引用绑定字面值
auto k = ci, & l = i; //k是整数,l是整型引用
auto& m = ci, * p = &ci; //m是整型常量引用,p是一个指向整型常量的指针。
//auto& n = i, * p2 = &ci; //错误,类型不和,i是int,ci是const int。
a = 42;
b = 32;
c = 42;
//d = 42;
//e = 42;
//f = 42;
}
练习2.35:判断下列定义推断出的类型是什么,然后编写程序进行验证。
#include
#include
using namespace std;
int main()
{
const int i = 42;
auto j = i; //j是整数
const auto& k = i; //k是整型常量引用
auto* p = &i; //p是指向整型常量的指针
const auto j2 = i, & k2 = i; //j2是整数,k2是整型常量引用
int h = 30;
cout << j << endl;
cout << k << endl;
p = &h; //指针p可以指向其他对象,但是不可以通过指针p来修改对象的值
cout << *p << endl;
cout << j2 << " " << k2 << endl;
return 0;
}
有时会遇到这种情况:希望从表达式的类型推断出要定义的变量的类型,但是不想用该表达式的值初始化变量。为了满足这一要求,C++11新标准引入了第二种类型说明符decltype,它的作用是选择并返回操作数的数据类型。在此过程中,编译器分析表达式并得到它的类型,却不实际计算表达式的值
decltype(f()) sum = x; //sum 的类型就是函数f的返回类型
编译器并不实际调用函数f,而是使用当调用发生时f的返回值类型作为sum的类型。换句话说,编译器为sum指定的类型是什么呢?就是假如f被调用的话将会返回的那个类型。
decltype 不会忽略掉顶层const。
如果decltype使用的表达式不是一个变量,则decltype返回表达式结果对应的类型。
如果表达是的内容是解引用操作,则decltype返回的是引用类型。
decltype和auto的另一处重要区别是,decltype的结果类型与表达式形式密切相关。有一种情况需要特别注意:**对于decltype所用的表达式来说,如果变量名加上了一对括号,则得到的类型与不加括号时会有不同。**如果decltype使用的是一个不加括号的变量,则得到的结果就是该变量的类型:如果给变量加上了一层或多层括号,编译器就会把它当成是一个表达式。变量是一种可以作为赋值语句左值的特殊表达式,所以这样的decltype就会得到引用类型:
练习2.36:关于下面的代码,请指出每一个变量的类型以及程序结束时它们各自的值。
#include
#include
using namespace std;
int main()
{
int a = 3, b = 4;
decltype(a) c = a; //c是int型,此时c = 3;
decltype((b)) d = a; //d是int& 型,此时d是a的引用,d =3;
++c;
++d;
cout << "c = " << c << endl;
cout << "a=" << a << " d=" << d << endl;
cout << "b= " << b << endl;
return 0;
}
运行结果为:
c = 4
a=4 d=4
b= 4
练习2.37:赋值是会产生引用的一类典型表达式,引用的类型就是左值的类型。也就是
说,如果是int,则表达式i=x的类型是int&。根据这一特点,请指出下面的代码
中每一个变量的类型和值。
int a = 3, b = 4;
decltype(a) c = a; //c是int型
decltype(a=b) d = a; //d是int &型
练习2.38:说明由decltype指定类型和由auto指定类型有何区别。请举出一个例子,decltype指定的类型与auto指定的类型一样;再举一个例子,decltype指定的类型与auto。指定的类型不一样。
const int ci = 0;
decltype(ci) d = 100; //d是const int型
auto a = ci; //a是整数
int i = 100;
int &ir = i;
decltype(ir+0) a = i;
auto b = ir;