请教一个 c++问题, auto 定义多个对象时的指针类型推演

2016-06-10 11:12:38 +08:00
 zby0826
C++ primer 中文第五版 62 页:
int i = 0;
const int ci = i;
auto e = &ci;
e 是一个指向整型常量的指针(对常量对象取地址是一种底层 const)
以上可以理解。

下面又说:
要在一条语句中定义多个变量,切记,符号&和*只从属于某个声明符,而非基本数据类型的一部分,因此初始值必须是同一种类型:

auto &m = ci, *p = &ci; // m 是对整型常量的引用, p 是指向整型常量的指针



既然说初始值必须是同一种类型,可是 ci 和&ci 明明不是同一种类型啊!
为什么合法?为什么 p 是指向整型常量的指针,而不是指向整型常量指针的指针?为什么 auto 被推演为 const int 所以表达式合法?为什么 auto 不是被推演为 const int* 然后表达式就不合法了呢?


是不是定义多个变量有什么机制??
如果单独定义 auto *p2 = &ci; 那么 p2 是不是就变为指向整型常量指针的指针了呢?是不是这里的 auto 就被推演为 const int*了呢?

为什么会有这种差异?

手机码字,格式什么的可能不太好,抱歉。
2179 次点击
所在节点    C
14 条回复
Sorrow
2016-06-10 11:49:00 +08:00
auto &m = ci, *p = &ci;
如果你不理解这行代码,请把 auto 换成 const int :
代码就变为:
const int &m = ci, *p = &ci;
zby0826
2016-06-10 11:51:08 +08:00
@Sorrow &ci 是指针,为什么不推演为 const int*
kindjeff
2016-06-10 11:59:59 +08:00
语法上的不统一啦, auto *p2 = &ci 和 auto p2 = &ci 推导出来是一样的
kindjeff
2016-06-10 12:12:18 +08:00
我想了一下应该把 auto 看做占位符, auto *p2 = &ci 的时候推导出来'auto'=='const int', auto p2 = &ci 的时候推导出来'auto'=='const int *'。
auto &m = ci, *p = &ci 的时候推导出来'auto'=='const int'。所以你写 auto *p = ci 就会报错,因为推导不出来 auto 这个位置应该放什么。
loveuqian
2016-06-10 12:21:17 +08:00
突然想起来。。轮子哥不混 v2 的啊?
@vczh
Sorrow
2016-06-10 12:23:49 +08:00
@zby0826 auto 是一个 placeholder ,它的用法和其他 declarator 一致,如果按照你的理解就破坏了这种语法规则。
onemoo
2016-06-10 14:45:34 +08:00
我觉得这个应该算是翻译时用词的问题。
描述这段相应的原文中是这样的:
“ Because a declaration can involve only a single base type, the initializers for all the variables in the declaration must have types that are consistent with each other ”
我粗译一下:
因为一句声明只能有一个 base type (这里的 base type 指的是 auto 所代表的类型),所以多个(被声明的)变量的 initializer 的类型必须能够相互配合一致。

“ The type that the compiler infers for auto is not always exactly the same as the initializer ’ s type ”
——编译器推断出来的 auto 类型并非一定与 initializer 的类型一致
“ when we use a reference as an initializer, the initializer is the corresponding object ”
——当我们用引用作为 initializer ,我们其实用的是“被引用的对象”,(推断出的也是被引用对象的类型)
这几句的意思就是初值的类型不一定和 auto 类型一致,只要它们能匹配“通常的声明规则”即可。 使用 auto 时,通常的声明规则仍是有效的。

所以,我感觉不应翻译为“因此初始值必须是同一种类型”,因为原文中始终用的是 consistent 而非 same ,原意为:后面各个变量的初始值的类型,必须能够[互相]与 auto 匹配。

你最后所说:如果单独定义 auto *p2 = &ci; 那么 p2 是不是就变为指向整型常量指针的指针了呢?是不是这里的 auto 就被推演为 const int*了呢?
这个 auto 就会被推断为 const int 类型, auto *p2 即是 const int *p2 , p2 不正是 const int 指针吗。
zby0826
2016-06-10 15:37:31 +08:00
@onemoo 首先谢谢…
你说的是中文版前面一页 p61 ,其实中文版也说了“编译器推断出来的 auto 类型有时候和初始值的类型并不完全一致,编译器会适当的改变结果类型使其更符合初始化规则”。但这里没有详细解释什么叫更符合初始化规则。
你最后的意思是 p2 是指针,不是指向指针的指针?这么说的话, auto *p2 = &ci; 和 auto p2 = &ci; 没有区别?所定义的 p2 就是完全一样的?在上自习,没带电脑,晚上回去跑一下看看…
zby0826
2016-06-10 15:45:18 +08:00
@kindjeff 为什么 auto *p2 = &ci 和 auto p2 = &ci 推导出来是一样的?

“ auto *p2 = &ci 的时候推导出来'auto'=='const int', auto p2 = &ci 的时候推导出来'auto'=='const int *'。”为什么会这样?依据是什么呢?前者为什么不能解释为指向指针的指针呢?
kindjeff
2016-06-10 15:52:24 +08:00
@zby0826 因为&ci 就是一个 const int*呀
zby0826
2016-06-10 16:20:43 +08:00
@kindjeff 我明白了,绕了个大圈子,我以为可以解释为 const int **p2 = &ci ,然而这句表达式本身就是完全错误的。所以疑惑都解开了,可能正如你所说 auto 就是类似占位符,对不同的声明符和类型修饰符做出不同的说明。谢谢了~
onemoo
2016-06-10 16:48:16 +08:00
所以, auto 相当于一道填空题:“____ *p2 = &ci ,请填入一个类型,使该表达式合法成立”。
你会填入 const int ,编译器也会推导出相同的结果,这个结果就是 auto 的类型。 你写出这个答案的依据就是你所学过的的“普通的声明规则”。
我给出前一页的那句话是因为:它所描述的就是这两页中的所有内容的原则。 也就是说等号左侧和右侧的这些类型必须是相互 consistent 的,判断是否 consistent 依据的就是 C++自身的“声明规则”。

关于 9L 中你的问题,“ auto *p2 = &ci 的时候推导出来'auto'=='const int', auto p2 = &ci 的时候推导出来'auto'=='const int *” 是的,会推导出这样的结果,原因现在你已经明白了吧。
但是如果这句是这样写的: auto *p2 = &ci, p3 = &ci; 就错了。因为根据 p2 ,编译器推导出 auto 应为 const int ,但根据 p3 ,又推导出了 auto 为 const int *,两者 inconsistent ,编译器就会报错了。
FrankHB
2016-06-11 05:17:35 +08:00
什么 base type ……现在的“入门”书已经没节操在这里生造概念了吗……难怪某糖看不起“底火”……
有点正确的基础的话真的就是一句话的事情……
WG21/N4594
7.1.6.4 auto specifier [dcl.spec.auto]
1 The auto and decltype(auto) type-specifiers are used to designate a placeholder type that will be replaced
later by deduction from an initializer. ...
(当然怎么 deduce 就要倒腾 Clause 14 了,没问题就可喜可贺。)
bravecarrot
2016-06-11 10:35:33 +08:00
auto 不可以替换的哦

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

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

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

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

© 2021 V2EX