尾随返回类型中的Type-id歧义

时间:2017-03-01 09:12:12

标签: c++ c++14 language-lawyer declaration

标准引用:

  

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(单独)?我不太清楚在标准中使用非终端时...

1 个答案:

答案 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

语法最近被enter image description here再次更改,将 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 中的符号->之后。