c++ 函数签名的语法规范(keyword/context 关键字顺序)是什么?
What are the syntax specifications (keyword/context keyword ordering) for c++ function signatures?
C++ 丰富的表现力和语法,使得在单个签名上使用该语言的多个功能有些困难。
例如我想声明一个成员函数[1] 为:
virtual
override
// 上下文关键字示例
noexcept
const
- 有尾随 return 类型
如果我们考虑到函数也可以是,那就更复杂了
- 默认
- 已删除
- final(对于虚拟方法)
- 模板
- 明确的专业化
[[deprecated]]
- ...还有很多我现在不能know/suspect
标准的措辞对我来说看起来很希腊语,甚至那不是真的,我不知道什么与什么一起工作(或者什么是句法错误,例如 [1] 可能甚至是非法的)。
我知道阅读各个功能(override、noexcept 等)会有所帮助,但是是否有关于如何在协作中使用它们的指南?(语法上 说话;我 不 expect/want 对功能的回答)
编辑
为了以防万一,我想破解的摘录如下
8.4.1 Function definitions have the form
function-definition: attribute-specifier-seqopt decl-specifier-seqopt declarator virt-specifier-seqopt function-body
如果您有规范的副本,则可以在每个部分中查找语法。听起来您想要一个 完整 指南来说明什么是正确的,什么是不正确的,规范是此信息的唯一真实来源。幸运的是,它并不难读,只是费时费力。
这是函数定义的语法,取自 N3690 的 8.4.1 节开头。我建议先阅读上下文无关语法入门(Wikipedia - 跳到示例)。请注意,每个人在编写上下文无关语法方面都有自己的差异,因此 C++ 规范中的语法将与您在维基百科或编译器教科书中看到的略有不同。
function-definition:
attribute-specifier-seqopt decl-specifier-seqopt declarator virt-specifier-seqopt function-body
function-body:
ctor-initializeropt compound-statement
function-try-block
= default ;
= delete ;
读到这里,我们看到 "function-body" 有四个选项,每行一个。两个备选方案 = delete
和 = default
,因此它们与 { ... }
更有趣的函数体所在的位置相同。 (函数 try 块 是一种在 C++ 中定义函数的晦涩方式,所以让我们忽略它。)
对于"function-definition",你可以看到它只有一行,所以只有一种定义函数的方法。行中的每一项都必须按顺序出现。带有 "opt" 下标的部分是可选的。所以,
- 属性优先
- 接下来声明说明符(例如,
static
、int
、extern
...)
- 之后的声明符(例如
function_name(int x, int y) -> int
)
- 之后的虚拟说明符(
override
或 final
)
- 最后一个函数体(这包括普通函数体
{ ... }
以及 = delete
和 = default
)
一旦你稍微练习阅读 CFG,它就会成为你的第二天性。唯一困难的部分是绕过 C++ 规范以找到您想要的所有定义。
备注
另请注意,语法只会告诉您语法。如果你只是阅读语法,你会写出像这样的废话:
// permissible, according to the grammar
extern static const void long short int int x;
阅读文本会解释你不能,例如,有一个 short long
,即使它是语法允许的。
另一个技巧是找到您要查找的定义。正如 Serthy 在下面所问的那样,您如何指定纯函数? = 0
去哪儿了?那么,你可以发现= 0
在9.2节中出现的是pure-specifier
,但它只能出现在member-declarator
上。所以它不能出现在function-definition
中,它只能出现在"declaration"中。声明和定义语法略有不同。
换句话说,你不能定义一个纯函数,但是你可以声明一个纯函数。
进一步阅读
如果您对此主题感兴趣,我推荐 编译器:原理、技术和工具,作者:Alfred V. Aho、Ravi Sethi 和 Jeffrey D. Ullman。
C++ 丰富的表现力和语法,使得在单个签名上使用该语言的多个功能有些困难。
例如我想声明一个成员函数[1] 为:
virtual
override
// 上下文关键字示例noexcept
const
- 有尾随 return 类型
如果我们考虑到函数也可以是,那就更复杂了
- 默认
- 已删除
- final(对于虚拟方法)
- 模板
- 明确的专业化
[[deprecated]]
- ...还有很多我现在不能know/suspect
标准的措辞对我来说看起来很希腊语,甚至那不是真的,我不知道什么与什么一起工作(或者什么是句法错误,例如 [1] 可能甚至是非法的)。
我知道阅读各个功能(override、noexcept 等)会有所帮助,但是是否有关于如何在协作中使用它们的指南?(语法上 说话;我 不 expect/want 对功能的回答)
编辑
为了以防万一,我想破解的摘录如下
8.4.1 Function definitions have the form
function-definition: attribute-specifier-seqopt decl-specifier-seqopt declarator virt-specifier-seqopt function-body
如果您有规范的副本,则可以在每个部分中查找语法。听起来您想要一个 完整 指南来说明什么是正确的,什么是不正确的,规范是此信息的唯一真实来源。幸运的是,它并不难读,只是费时费力。
这是函数定义的语法,取自 N3690 的 8.4.1 节开头。我建议先阅读上下文无关语法入门(Wikipedia - 跳到示例)。请注意,每个人在编写上下文无关语法方面都有自己的差异,因此 C++ 规范中的语法将与您在维基百科或编译器教科书中看到的略有不同。
function-definition: attribute-specifier-seqopt decl-specifier-seqopt declarator virt-specifier-seqopt function-body function-body: ctor-initializeropt compound-statement function-try-block = default ; = delete ;
读到这里,我们看到 "function-body" 有四个选项,每行一个。两个备选方案 = delete
和 = default
,因此它们与 { ... }
更有趣的函数体所在的位置相同。 (函数 try 块 是一种在 C++ 中定义函数的晦涩方式,所以让我们忽略它。)
对于"function-definition",你可以看到它只有一行,所以只有一种定义函数的方法。行中的每一项都必须按顺序出现。带有 "opt" 下标的部分是可选的。所以,
- 属性优先
- 接下来声明说明符(例如,
static
、int
、extern
...) - 之后的声明符(例如
function_name(int x, int y) -> int
) - 之后的虚拟说明符(
override
或final
) - 最后一个函数体(这包括普通函数体
{ ... }
以及= delete
和= default
)
一旦你稍微练习阅读 CFG,它就会成为你的第二天性。唯一困难的部分是绕过 C++ 规范以找到您想要的所有定义。
备注
另请注意,语法只会告诉您语法。如果你只是阅读语法,你会写出像这样的废话:
// permissible, according to the grammar
extern static const void long short int int x;
阅读文本会解释你不能,例如,有一个 short long
,即使它是语法允许的。
另一个技巧是找到您要查找的定义。正如 Serthy 在下面所问的那样,您如何指定纯函数? = 0
去哪儿了?那么,你可以发现= 0
在9.2节中出现的是pure-specifier
,但它只能出现在member-declarator
上。所以它不能出现在function-definition
中,它只能出现在"declaration"中。声明和定义语法略有不同。
换句话说,你不能定义一个纯函数,但是你可以声明一个纯函数。
进一步阅读
如果您对此主题感兴趣,我推荐 编译器:原理、技术和工具,作者:Alfred V. Aho、Ravi Sethi 和 Jeffrey D. Ullman。