2.5 处理类型

两种定义类型别名的方法

  1. typedef
typedef  double   wages;				//wages是double的同义词
typedef  wages   baser  , *p;			//base是double的同义词,p是double的同义词
  1. using 别名声明
using  SI = Sales_item;				//SI是Sales_item的同义词

类型别名和类型的名字等价,只要是类型的名字能出现的地方,就能使用类型别名。
2.5 处理类型_第1张图片

auto类型说明符

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类型有时候和初始值的类型并不完全一样,编译器会适当地改变结构类型使其更符合出事化规则。如:

  1. auto 推断引用类型时,实际使用的是引用绑定的对象。
  2. auto 一般会忽略掉顶层 const,同时底层const则会保存下来。
    在这里插入图片描述
  3. 如果希望推断出的auto类型是一个顶层const,需要明确指出。
const auto f = ci;     //ci的推演类型是int,f是const int。
  1. 将引用的类型设为 auto
    在这里插入图片描述
    测试程序:
#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;
}

decltype类型指示符

有时会遇到这种情况:希望从表达式的类型推断出要定义的变量的类型,但是不想用该表达式的值初始化变量。为了满足这一要求,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.5 处理类型_第2张图片
练习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。指定的类型不一样。

  1. decltype不会忽略顶层const,auto会忽略顶层const。
const int ci = 0;
decltype(ci) d = 100; //d是const int型
auto a = ci;			//a是整数
  1. decltype和auto的另一处重要区别是,decltype的结果类型与表达式形式密切相关。有一种情况需要特别注意:**对于decltype所用的表达式来说,如果变量名加上了一对括号,则得到的类型与不加括号时会有不同。**如果decltype使用的是一个不加括号的变量,则得到的结果就是该变量的类型:如果给变量加上了一层或多层括号,编译器就会把它当成是一个表达式。变量是一种可以作为赋值语句左值的特殊表达式,所以这样的decltype就会得到引用类型:
int i = 100;
int &ir = i;
decltype(ir+0) a = i;
auto b = ir;

你可能感兴趣的:(C++,primer,学习,指针,c++,cpp)