如何理解“包含省略号的抽象声明符只能在参数声明中使用”

jac*_*k X 4 c++ language-lawyer

考虑以下引用,它说:
[dcl.fct]/16

包含省略号的 declarator-id 或 abstract-declarator 只能在参数声明中使用。[...]

我同意包含省略号的 declarator-id 只能用在参数声明中,因为我们不能...id-expression在任何地方使用类似的东西,它只能出现在参数声明中,所以 100% 清楚。但是,关于抽象包含省略号的声明符只能用于参数声明,请考虑以下代码:

#include <iostream>
#include <tuple>
template<typename...T>
void func(T...){
  std::tuple<T...> tup;  //#1
}
Run Code Online (Sandbox Code Playgroud)

[dcl.name]

类型标识:

类型说明符序列抽象声明符(选择)

怎么样#1,它不是参数声明,但是,在该上下文中的type-id中使用了包含省略号的抽象声明符。所以,我对抽象声明符的理解是错误的吗?

Mar*_*ark 5

省略号不是 a 的一部分type-id,而是 a 的一部分template-argument-list

如果我们从[temp.names]应用以下语法

简单模板 ID:
    模板名称<模板参数列表选择>

模板名称:
    标识符

模板参数列表:
    模板参数 ...选择
    [...]

模板参数:
    类型标识
    [...]

以你的例子,我们得到:

   std::tuple<T...> tup;
//      tuple<T...>       simple-template-id
//      tuple             template-name
//            T...        template-argument-list
//            T           template-argument, type-id
Run Code Online (Sandbox Code Playgroud)

然后,[temp.arg]/9

模板参数后跟省略号是一包扩展。

适用,这正是我们所期望的。