[英]Where in the Standard does it say that the declaration `auto f()() ->int;` is not allowed?
I know I'm being pedantic here, but I'm just trying to understand the C++ grammar production. 我知道我在这里很迂腐,但我只是想了解C ++的语法生成。
I will start with a simple-declaration . 我将从一个简单的声明开始 。
simple-declaration : 简单声明 :
decl-specifier-seq opt init-declarator-list opt decl-specifier-seq opt init-declarator-list opt
decl-specifier-seq : decl-specifier-seq :
decl-specifier DECL说明符
decl-specifier : decl-specifier :
type-specifier 类型说明符
type-specifier : 类型说明符 :
trailing-type-specifier 拖尾型说明符
trailing-type-specifier : trailing-type-specifier :
simple-type-specifier 简单型说明符
simple-type-specifier : 简单类型说明符 :
char 烧焦
int INT
... ...
auto 汽车
Now, I'll look into the definition of a init-declarator-list . 现在,我将研究init-declarator-list的定义。
init-declarator-list : init-declarator-list :
init-declarator 初始化声明符
init-declarator : init-declarator :
declarator 声明符
declarator : 声明者 :
noptr-declarator parameters and qualifiers trailing return type (*2) noptr-declarator 参数和限定符 尾随返回类型 (* 2)
noptr-declarator : noptr-declarator :
declarator-id attribute-specifier-seq opt declarator-id attribute-specifier-seq opt
noptr-declarator parameters and qualifiers (*1) noptr-declarator 参数和限定符 (* 1)
parameters and qualifiers : 参数和限定符 :
( parameter-declaration-clause ) cv-qualifiers opt ... (all optionals) ( parameter-declaration-clause ) cv-qualifiers opt ...(所有选项)
trailing-return-type : trailing-return-type :
- > trailing-type-specifier-seq - > trailing-type-specifier-seq
trailing-type-specifier-seq : trailing-type-specifier-seq :
trailing-type-specifier See the definition of a traling-type-specifier above. trailing-type-specifier请参阅上面的traling-type-specifier的定义。
Replacing noptr-declarator by a declarator-id in (*1) , using the previous definition of noptr-declaration , we arrive at the following definition of nonptr-declarator : 用(* 1)中的declarator-id替换noptr-declarator ,使用之前的noptr-declaration定义,我们得到了nonptr-declarator的以下定义:
noptr-declaration : noptr-declaration :
declarator-id parameters and qualifiers declarator-id 参数和限定符
Now replacing noptr-declarator , parameters and qualifiers and trailing-return-type in (*2) by each definition given above, we obtain the following for declarator : 现在用上面给出的每个定义替换(* 2)中的noptr-declarator , 参数和限定符以及trailing-return-type ,我们为声明 符获取以下内容:
declarator : 声明者 :
declarator-id ( parameter-declaration-clause ) ( parameter-declaration-clause ) - > declarator-id ( parameter-declaration-clause )( 参数声明子句 ) - >
simple-type-specifier 简单型说明符
With this last result we could say that the grammar allows the following declaration of a function f
: 有了这个最后的结果,我们可以说语法允许函数f
的以下声明:
auto f()() -> int;
which of course is not valid. 这当然是无效的。 But I couldn't find anything in the Standard saying, directly or indirectly, that this construction is ill-formed. 但我无法在标准中找到任何直接或间接说明这种结构不正确的内容。
The error messages from GCC
( f
declared as function returning a function) and clang
( auto
return without trailing return type; deduced return types are a C++1y extensions) didn't help in this regard either. 来自GCC
的错误消息( f
声明为函数返回函数)和clang
( auto
返回没有尾随返回类型;推断的返回类型是C ++ 1y扩展)在这方面也没有帮助。
[dcl.fct] /8: [dcl.fct] / 8:
[...] Functions shall not have a return type of type array or function, although they may have a return type of type pointer or reference to such things. [...]函数不应具有类型数组或函数的返回类型,尽管它们可能具有类型指针的返回类型或对此类事物的引用。 [...] [...]
In fact, the gcc error message is quite helpful: The grammar does in fact allow auto f()() -> int
, but this syntactically correct declaration is semantically invalid. 实际上,gcc错误消息非常有用:语法实际上允许auto f()() -> int
,但这种语法正确的声明在语义上是无效的。 It would describe a function returning a function returning int
. 它将描述一个函数返回一个返回int
的函数。 See the answer of ecatmur for the standard quote disallowing that. 请参阅ecatmur的答案,以获取禁止使用的标准报价。
To understand the parse, work like this. 要理解解析,请像这样工作。 f
is what you want to declare. f
是你想要宣布的。 Parse to the right, you'll find an empty argument list, so f()
is a valid expression, and the type of that expression gets declared. 向右解析,您将找到一个空参数列表,因此f()
是一个有效的表达式,并声明该表达式的类型。 Parse again to the right, you'll find an argument list again , so the return type of f
is a function taking zero arguments. 再次向右解析,你会再次找到一个参数列表,所以f
的返回类型是一个零参数的函数。 Parse again to the right, and you will hit the end (the ->
arrow), so parse to the left to find the result type, which is auto, and gets replaced by the type past the arrow. 向右再次解析,然后你将到达终点( ->
箭头),因此向左解析以找到结果类型,即auto,并被箭头后面的类型替换。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.