c++ - decl-specifier-seq 语法树中什么样的类型说明符可以表示模板参数包时的类型说明符
问题描述
template<typename...T>
void func(T...){
}
考虑上面的代码,这是标准提到的一个案例:
当省略号出现在参数声明子句的末尾而没有前面的逗号时,就会出现句法歧义。在这种情况下,如果参数的类型命名为未扩展的模板参数包或包含 auto ,则省略号将被解析为抽象声明符的一部分;否则,它被解析为参数声明子句的一部分。
因此,参数声明是以下形式:
dcl.fct#3
参数声明:
属性说明符序列(选择) decl 说明符序列抽象声明符(选择)
其中,抽象声明符表示,但是,我在的语法树中...
找不到类型说明符可以表示。decl-specifier-seq
T
声明说明符:
- 存储类说明符
- 定义类型说明符
- 函数说明符
- 朋友
- 类型定义
- 常量表达式
- 排队
声明说明符序列:
- decl-specifier 属性-说明符-seq (opt)
- decl 说明符 decl 说明符序列
因为T
这里是一个未扩展的模板参数类型。所以T
不是typedef-name
,因为这个:
temp.param#3
标识符不跟在省略号后面的类型参数将其标识符定义为模板声明范围内的typedef-name(如果没有模板声明)或模板名(如果使用模板声明)。[注意:模板参数可以是类模板或别名模板。
所以,我想知道 decl-specifier-seq 语法树中的什么东西可以表示T
尚未扩展的模板参数包?到目前为止,我还没有找到与T
. 如果我错过了什么,请纠正我。
更新
对于这个问题,我正在深入研究temp.variadic#5部分,我发现了一些内容:
为了确定参数包是否满足关于除参数包之外的实体的规则,参数包被认为是由其出现的模式的实例化产生的实体。
我对这句话的阅读是,参数包需要满足关于参数声明的规则,因此在调用 like 函数时func(0,0.1)
,包扩展模式的实例化int,double
分别是,由于:
包扩展由一个模式和一个省略号组成,其实例化会在列表中产生零个或多个模式的实例化(如下所述)
- 在函数参数包中([dcl.fct]);模式是没有省略号的参数声明。
因此,这些实例化的结果被用作类型说明符。这意味着int,double
将是这种情况下这些参数声明的类型说明符func(0,0.1)
,但是这是我的阅读,我不确定这是否是这个问题的相关规则。
这将导致另一个问题,因为template<typename...T> void func(T...);
,参数包 不是函数参数包,因为这个规则:
包含省略号的 declarator-id 或 abstract-declarator 只能在参数声明中使用。这样的参数声明就是一个参数包。当它是 parameter-declaration-clause 的一部分时,参数包是函数参数包。[注意:否则,参数声明是模板参数列表的一部分,参数包是模板参数包;见 [temp.param]。——尾注]
在我的问题中,参数包被解析为抽象声明符的一部分,而不是参数声明子句的一部分,因为第一个引号就是这么说的。因此,参数包根本不被认为是函数参数包吗?现在,我认为这个问题变得更加复杂。我期待这个问题的答案。
解决方案
推荐阅读
- php - Amazon Athena“打开 Hive 拆分时出错”访问被拒绝错误
- flutter - Flutter 学习路线图
- excel - 使用 VBA 宏在 Excel 中查找替换希腊字符
- python - 定义 Glop Solver 约束时出现“TypeError:'int' object is not subscriptable”?
- python - Python中有用户提供的键功能的字典吗?
- salesforce - 将自定义设置元数据部署到“企业”组织时出错 - Salesforce
- r - 积分和数值优化 (nlminb) R
- python - 当 Debug = False 时,Django 站点找不到管理样式或媒体文件
- .net - 使用 SQLQuery 在 .NET 应用程序中执行存储过程返回不正确的值
- powershell - 根据文件名和扩展名将文件移动到与文件名匹配的文件夹?