标准中哪里说不允许声明 `auto f()() ->int;`?
Where in the Standard does it say that the declaration `auto f()() ->int;` is not allowed?
我知道我在这里很迂腐,但我只是想了解 C++ 语法产生式。
我将从一个简单声明开始。
简单声明:
decl-specifier-seqopt init-declarator-listopt
decl-specifier-seq:
decl-说明符
声明说明符:
类型说明符
类型说明符:
尾随类型说明符
尾随类型说明符:
简单类型说明符
简单类型说明符:
字符
整数
...
自动
现在,我将研究 init-declarator-list 的定义。
init-declarator-list:
初始化声明符
初始化声明符:
声明符
声明符:
noptr-声明符 参数和限定符 尾随return类型 (* 2)
noptr-声明符:
declarator-id attribute-specifier-seqopt
noptr-声明符 参数和限定符 (*1)
参数和限定符:
(参数声明子句) cv-qualifiersopt ...(所有选项)
尾随-return-类型:
-> 尾随类型说明符序列
尾随类型说明符序列:
trailing-type-specifier 请参阅上面 traling-type-specifier 的定义。
在 (*1) 中用 declarator-id 替换 noptr-declarator,使用 noptr-declaration 的先前定义,我们得出以下 nonptr-declarator 的定义:
noptr-声明:
declarator-id 参数和限定符
现在替换 noptr-declarator、参数和限定符 和 trailing-return-type in (*2) 根据上面给出的每个定义,我们为 declarator 获得以下内容:
声明符:
declarator-id (参数声明子句) (参数声明子句) ->
简单类型说明符
根据最后的结果,我们可以说语法允许函数的以下声明 f
:
auto f()() -> int;
这当然是无效的。但是我在标准中找不到任何直接或间接的说法,说这个结构是错误的。
错误消息来自 GCC
(f
声明为函数 returning 函数)和 clang
(auto
return 没有尾随 return 类型;推导的 return 类型是 C++1y 扩展)在这方面也没有帮助。
[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. [...]
事实上,gcc 错误消息非常有用:语法确实允许 auto f()() -> int
,但是这个语法上正确的声明在语义上是无效的。它会描述一个函数 returning 一个函数 returning int
。请参阅 ecatmur 的答案,了解不允许这样做的标准报价。
要理解解析,请像这样工作。 f
就是你要声明的。向右解析,你会发现一个空的参数列表,所以 f()
是一个有效的表达式,并且声明了该表达式的类型。再向右解析,又是一个参数列表,所以f
的return类型是零参数函数。再次向右解析,您将到达终点(->
箭头),因此向左解析以找到结果类型,即自动,并被箭头后面的类型替换。
我知道我在这里很迂腐,但我只是想了解 C++ 语法产生式。
我将从一个简单声明开始。
简单声明:
decl-specifier-seqopt init-declarator-listopt
decl-specifier-seq:
decl-说明符
声明说明符:
类型说明符
类型说明符:
尾随类型说明符
尾随类型说明符:
简单类型说明符
简单类型说明符:
字符
整数
...
自动
现在,我将研究 init-declarator-list 的定义。
init-declarator-list:
初始化声明符
初始化声明符:
声明符
声明符:
noptr-声明符 参数和限定符 尾随return类型 (* 2)
noptr-声明符:
declarator-id attribute-specifier-seqopt
noptr-声明符 参数和限定符 (*1)
参数和限定符:
(参数声明子句) cv-qualifiersopt ...(所有选项)
尾随-return-类型:
-> 尾随类型说明符序列
尾随类型说明符序列:
trailing-type-specifier 请参阅上面 traling-type-specifier 的定义。
在 (*1) 中用 declarator-id 替换 noptr-declarator,使用 noptr-declaration 的先前定义,我们得出以下 nonptr-declarator 的定义:
noptr-声明:
declarator-id 参数和限定符
现在替换 noptr-declarator、参数和限定符 和 trailing-return-type in (*2) 根据上面给出的每个定义,我们为 declarator 获得以下内容:
声明符:
declarator-id (参数声明子句) (参数声明子句) ->
简单类型说明符
根据最后的结果,我们可以说语法允许函数的以下声明 f
:
auto f()() -> int;
这当然是无效的。但是我在标准中找不到任何直接或间接的说法,说这个结构是错误的。
错误消息来自 GCC
(f
声明为函数 returning 函数)和 clang
(auto
return 没有尾随 return 类型;推导的 return 类型是 C++1y 扩展)在这方面也没有帮助。
[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. [...]
事实上,gcc 错误消息非常有用:语法确实允许 auto f()() -> int
,但是这个语法上正确的声明在语义上是无效的。它会描述一个函数 returning 一个函数 returning int
。请参阅 ecatmur 的答案,了解不允许这样做的标准报价。
要理解解析,请像这样工作。 f
就是你要声明的。向右解析,你会发现一个空的参数列表,所以 f()
是一个有效的表达式,并且声明了该表达式的类型。再向右解析,又是一个参数列表,所以f
的return类型是零参数函数。再次向右解析,您将到达终点(->
箭头),因此向左解析以找到结果类型,即自动,并被箭头后面的类型替换。