标准引用:
trailing-return-type中的type-id包括尽可能长的abstract-declarators序列。
注意:这解决了数组和函数声明符的模糊绑定。
示例:
auto f()->int(*)[4]; // function returning a pointer to array[4] of int
// not function returning array[4] of pointer to int
我想知道,这个给定的代码有什么含糊之处?
标准中提到的歧义通常是由于语法本身的模糊性,而在这种情况下,给定的字符序列总是被解释为尾随返回类型(即单一类型),并且不应该存在歧义它是哪一个。
顺便问一下,为什么会提到type-id?我的意思是,正式地说它只能出现在不同于trailing-return-type的代码不同的地方。或者只是非正式地提到,因为所有可以解析(自身)为trailing-return-type的东西也可以解析为type-id(单独)?我不太清楚在标准中使用非终端时...
答案 0 :(得分:1)
在N2541中, trailing-return-type 可能出现在任何函数声明符中。这意味着auto (*f() -> int);
是一个有效的声明。那时auto f()->int(*)[4];
可能被解释为具有auto (f()->int(*))[4];
的相同含义(声明f
作为函数返回指向int的指针的数组[4]。它也可以按照我们通常期望的方式解释,即[4]
是 trailing-return-type 的一部分,声明声明一个函数返回一个指向数组[4]的指针。 INT。当时添加了引用的段落以解决这种模糊性。
在N2541被投票进入标准后,CWG 681更改了语法,以确保 trailing-return-type 只能出现在顶级函数声明器中;因此[4]
必须是 trailing-return-type 的一部分。不再含糊不清。但是,CWG 681没有删除消歧规则,这似乎是一种疏忽。
最近由CWG 2040纠正了这种疏忽,删除了现在没用的段落。
N2541还允许 type-id 出现在符号->
之后,这会在auto f() -> struct S { };
等声明中带来歧义。这是CWG 770并由N2927解析,CWG 2141将 trailing-return-type 定义为符号->
,后跟尾随类型说明符-seq 后跟可选的 abstract-declarator 。但是N2927不会修改消歧规则,即使现在 trailing-return-type 中没有 type-id 也没有意义。
type-id 是 type-specifier-seq ,后跟可选的 abstract-declarator 。那时类类型或枚举类型定义可能出现在 type-specifier-seq 中,但不能出现在 trailing-type-specifier-seq 中。这使-> struct S {}
成为无效的尾随返回类型,但struct S {}
是有效的 type-id 。
语法最近被再次更改,将 type-specifier-seq 重命名为 defined-type-specifier-seq 并重命名 trailing-type-specifier-seq 到 type-specifier-seq 。 type-id 仍被定义为 type-specifier-seq ,后跟可选的 abstract-declarator 。最终结果是类型或枚举类型定义现在可能不会出现在 type-id 中。现在,任何 type-id 都可能出现在 trailing-return-type 中的符号->
之后。