首页 > 解决方案 > decl-specifier-seq 语法树中什么样的类型说明符可以表示模板参数包时的类型说明符

问题描述

template<typename...T>
void func(T...){
}

考虑上面的代码,这是标准提到的一个案例:

当省略号出现在参数声明子句的末尾而没有前面的逗号时,就会出现句法歧义。在这种情况下,如果参数的类型命名为未扩展的模板参数包或包含 auto ,则省略号将被解析为抽象声明符的一部分;否则,它被解析为参数声明子句的一部分。

因此,参数声明是以下形式:
dcl.fct#3

参数声明:

属性说明符序列(选择) decl 说明符序列抽象声明符(选择)

其中,抽象声明符表示,但是,我在的语法树中...找不到类型说明符可以表示。decl-specifier-seqT

dcl.spec#1

声明说明符:

声明说明符序列:

  • 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分别是,由于:

temp.variadic#4

包扩展由一个模式和一个省略号组成,其实例化会在列表中产生零个或多个模式的实例化(如下所述)

  • 在函数参数包中([dcl.fct]);模式是没有省略号的参数声明。

因此,这些实例化的结果被用作类型说明符。这意味着int,double将是这种情况下这些参数声明的类型说明符func(0,0.1),但是这是我的阅读,我不确定这是否是这个问题的相关规则。

这将导致另一个问题,因为template<typename...T> void func(T...);,参数包 不是函数参数包,因为这个规则:

包含省略号的 declarator-id 或 abstract-declarator 只能在参数声明中使用。这样的参数声明就是一个参数包。当它是 parameter-declaration-clause 的一部分时,参数包是函数参数包。[注意:否则,参数声明是模板参数列表的一部分,参数包是模板参数包;见 [temp.param]。——尾注]

在我的问题中,参数包被解析为抽象声明符的一部分,而不是参数声明子句的一部分,因为第一个引号就是这么说的。因此,参数包根本不被认为是函数参数包吗?现在,我认为这个问题变得更加复杂。我期待这个问题的答案。

标签: c++c++17language-lawyer

解决方案


推荐阅读