首页 > 其他分享 >auto与decltype

auto与decltype

时间:2022-10-01 10:11:21浏览次数:42  
标签:ci decltype int auto 顶层 类型 const

auto 关键词

auto 仅仅是一个占位符,在编译器期间它会被真正的类型所替代。

使用 auto 类型推导的变量必须马上初始化,这个很容易理解,因为 auto 在 C++11 中只是“占位符”,并非如 int 一样的真正的类型声明。

顶层 const 和底层 const

由于指针本身是一个对象,又可以指向一个对象,所以存在顶层(指针本身这个对象)和底层 const(指针指向的对象

int i = 0;
int *const p1 = &i;               // 这里 const 是顶层 const
const int ci = 42;                // 这里 const 是顶层 const(用于表征某个对象是常量,不涉及指针)
const int *p2 = &ci;              // 这里 const 是底层 const(用于表征指针指向的对象是常量,涉及指针)
const int *const p3 = p2;         // 左边是底层 const,右边是顶层 const
const int &r = ci;                // 用于声明引用的 const 都是底层 const

当执行对象的拷贝时,常量是顶层 const 还是底层 const 有着明显的区别:

// 顶层 const 不影响对象的拷贝操作
i = ci; // 正确,ci 的顶层 const 不影响该对象拷贝操作 p2 = p3; // 正确,p3 的顶层 const 不影响该对象拷贝操作(p2,p3同时指向相同的对象类型)

// 在执行对象拷贝时,两边的底层 const 必须一致,或者两个对象的数据类型必须能够转换
int *p = p3 // 错误,p3 有底层 const 而 p 没有
p2 = p3 // 正确,p2, p3都有底层 const
p2 = &i // 正确,右边的 int* 能转换为 const int*
int &r = ci // 错误,const int 不能转换为 int
const int &r2 = i; // 正确,int 能转换为 const int(也可以理解为:const int& 能绑定在一个普通的 int 上)

auto 类型推导规则

1. 简单推导

auto n = 10;                                           // auto 为 int
auto f = 12.8;                                         // auto 为 double
auto p = &n;                                           // auto 为 int*
auto url = "http://c.biancheng.net/cplus/";            // auto 为 const char*, 即指向常量字符的指针


// 在本例中,编译器根据第一个子表达式已经推导出 auto 为 int 类型,那么后面的 m 也只能是 int 类型,如果写作 m = 12.5 就是错误的
int n = 20;
auto *p = &n, m = 99;

2.省略引用

引用实际是代表引用的对象,特别当引用作为初始值时,真正参与初始化的其实是引用对象的值

int i = 0;
int &r = i;
auto a = r;         // auto 为 int

3. 省略顶层 const

int i = 0;
const int ci = i;
const int &cr = ci;

auto b = ci;               // auto 为 int,忽略顶层 const
auto c = cr;               // auto 为 int,忽略顶层 const 和 引用
auto d = &i;               // auto 为 int*
auto e = &ci;              // auto 为 const int*(即指向一个常量整数的指针)

4. 显式声明顶层 const

const auto f = ci;       // ci 为 const int;auto 为 int;f 的类型为 const int

5. 显示声明引用(保留顶层 const)

设置一个类型为 auto 的引用时,初始值中的 顶层 const 得以保留。

auto &g = ci;           // ci 为 const int;auto 为 const int;g 的类型为 const int&
auto &h = 42 // 错误,不能为非常量引用 绑定 字面值
const auto &j = 42; // 正确,可以为常量引用 绑定 字面值

6. 一个语句中定义多个变量

每个表达式中的初始值的类型要保持一致

// ci 为 const int 类型
auto &m = ci, *p = &ci;        // m 的类型是 const int&(对常量整数的引用);p 的类型是 const int*(指向常量整数的指针)[ci 和 &ci 的类型当然一致]
auto &n = i, *p2 = &ci; // 错误,i 和 &ci 的类型不一致 (i 的类型是 int,而 &ci 的类型是 const int)


 auto 的限制

1. 使用 auto 的时候必须对变量进行初始化;

2. auto 不能在函数的参数中使用。(违反第一条原则)

3. auto 不能作用于类的非静态成员变量(也就是没有 static 关键字修饰的成员变量)中。

4. auto 关键字不能定义数组,比如下面的例子就是错误的:

char url[] = "http://c.biancheng.net/";

auto str[] = url; //arr 为数组,所以不能使用 auto

5. auto 不能作用于模板参数,请看下面的例子:

template <typename T>
class A{
    //TODO:
};

int  main(){
    A<int> C1;
    A<auto> C2 = C1;  //错误
    return 0;
}

 

decltype 关键词

decltype 推导规则

decltype 的推导规则主要有以下3条:
  1. 如果 exp 是一个不被括号( )包围的表达式,或者是一个类成员访问表达式,或者是一个单独的变量,那么 decltype(exp) 的类型就和 exp 一致,这是最普遍最常见的情况。
  2. 如果 exp 是函数调用,那么 decltype(exp) 的类型就和函数返回值的类型一致。
  3. 如果 exp 是一个左值,或者被括号( )包围,那么 decltype(exp) 的类型就是 exp 的引用;假设 exp 的类型为 T,那么 decltype(exp) 的类型就是 T&。

标签:ci,decltype,int,auto,顶层,类型,const
From: https://www.cnblogs.com/czw-yibao/p/16655539.html

相关文章