C++中`auto`这个关键字的一点疑惑。

2018-11-29 16:50:36 +08:00
 codechaser
int foo = 11;
const int &a = 10;
int *p = &foo;

auto x = foo;
auto y = a;
auto &yy = a;
auto pp = p;
auto *ppp = p;

cout << y << endl;
cout << yy << endl;
cout << pp << endl;
cout << ppp << endl;

输出:

10
10
0x61fefc
0x61fefc

这段程序的前面我都理解,到了pp这里我就有点疑惑了,C++ Primer 上说auto会推断出基本数据类型,那么按理说*这种指针声明也应该去掉了,所以auto *ppp = p;才是正确的吧?但是auto pp = p;与这一句输出了指针的值相同的结果,这是为什么呢?在网上找了一下,发现没有什么太好的解释,求教。

3044 次点击
所在节点    C
18 条回复
codehz
2018-11-29 16:59:35 +08:00
codehz
2018-11-29 17:01:27 +08:00
基本上就是和 decay 表现一致,可以看这个
codechaser
2018-11-29 17:06:29 +08:00
@codehz 看了一下,意思是说会隐式转换吗?我刚接触 C++,这个文档看的云里雾里的。😂
after1990s
2018-11-29 17:25:54 +08:00
auto 的类型推导和模板是基本一致的。

对于刚入门的来说,这个话题有点过难了。
codehz
2018-11-29 17:26:27 +08:00
auto 的类型 deduce 规则和 decay 的结果是一致的,其实就是一种类型的退化,把 cv 限定符 /引用 /不规范的函数类型干掉了。。(标准是 10.1.7.4.1 Placeholder type deduction [dcl.type.auto.deduct] 写的比较混乱,我个人总结就是把 auto 当作 std::decay_t<decltype(rhs)>这样去理解。。。
Yvette
2018-11-29 17:30:26 +08:00
首先明确 auto 的 * 是声明符的一部分,不是 base type 的一部分。

这样理解吧,因为 p 的 type 是 int *,base type 为 int,所以 auto deduce 出来 pp 为 int * 是合理的。而 ppp 声明中 * 是作用于 auto,用来明确 p 必须为 pointer,否则报错;如果不加 * (如 pp 这种情况)则如果 p 不是 pointer 也不会报错。
Yvette
2018-11-29 17:43:22 +08:00
总的来说就是 auto 后面 * 的作用是为了确保赋值符右边为 pointer 而不是为了声明新的变量为 pointer,虽然效果一样。而 auto 本身的作用是用赋值符右边的 type (不是 base type ) deduce 出新变量的 type。把声明 pp 和 ppp 中的 p 换成一个 int (比如 foo )跑一遍看看报错可能容易理解一些。
codechaser
2018-11-29 17:45:16 +08:00
@Yvette `base type 为 int,所以 auto deduce 出来 pp 为 int * 是合理的。`既然是 int 的,那么 pp 为 int *为什么就合理了呢?
Yvette
2018-11-29 17:53:30 +08:00
@codechaser 因为 p 的 type 是 int *

auto 的结果与 base type 无关,而是与 type 有关,提了句 base type 是为了稍微纠正一下
Yvette
2018-11-29 17:59:28 +08:00
@codechaser 简单来说就是两点:
1. auto 的结果为忽略了 top-level const 的 type
2. auto 的 type modifier 是为了确保右边返回的 type,而不是为了隐式转换
codechaser
2018-11-29 18:58:38 +08:00
@Yvette 谢谢!
Akiyu
2018-11-29 19:22:15 +08:00
上面那位 dalao 说得我都晕了
本着 less is more 的原则, 你这么简单记一下:
auto 会去除顶层 const 和引用属性

@btw: 如果你拿不准的话 decltype 可以推断出完整的属性

(如果我没弄错的话)
turi
2018-11-29 19:49:20 +08:00
Effective Modern C++ 里面讲解的很清楚,基本上就是 4 楼的意思
codechaser
2018-11-29 20:09:12 +08:00
@Akiyu auto 是会去除顶层 const 和引用属性,可是我不解的是 pp 和 ppp 都被推断成了 int *类型。
codehz
2018-11-30 05:34:57 +08:00
原来你问这个啊,这样的话你可以把 auto 理解为类型占位符,和方程里的未知数一个意思,事实上文档里就是这么写的。。。
aijam
2018-11-30 07:29:33 +08:00
感觉 lz 对指针写在等号左边和右边的语义不同不太熟悉。
对于等号右边的指针 p 来说,p 的类型是 int*, *p 的类型是一个 int。
当你写 auto pp = p,auto 推断出 pp 和 p 一样都是 int*,此时 pp == p == 0x61fefc
当你写 auto pp = *p, auto 推断出 pp 和*p 一样都是 int,此时 pp == *p == 11
逻辑很自然啊。
aijam
2018-11-30 07:38:03 +08:00
同理,auto *ppp 声明了 ppp 是一个指针,但我们不知道这个指针指向的类型是什么,需要 auto 来推导 ppp 是什么类型的指针。那么当你写 auto *ppp = p,说明 ppp 和 p 一样都是 int*。
codechaser
2018-11-30 09:45:09 +08:00
@aijam 这样的啊?谢谢啊!

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/512785

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX