首页 > 解决方案 > 模板参数部分中关于包扩展的一些混淆

问题描述

temp.param#15

如果模板参数是在其可选标识符之前带有省略号的类型参数,或者是声明参数包 ([dcl.fct]) 的参数声明,则模板参数是模板参数包。作为参数声明的模板参数包,其类型包含一个或多个未扩展的参数包,是包扩展。类似地,作为类型参数的模板参数包,其模板参数列表包含一个或多个未扩展的参数包,是包扩展。作为包扩展的模板参数包不应扩展在同一模板参数列表中声明的参数包。[ 例子:

template <class... Types> class Tuple;                // Types is a template type parameter pack
                                                      // but not a pack expansion
template <class T, int... Dims> struct multi_array;   // Dims is a non-type template parameter pack
                                                      // but not a pack expansion
template<class... T> struct value_holder {
  template<T... Values> struct apply { };             // Values is a non-type template parameter pack
                                                      // and a pack expansion
};
template<class... T, T... Values> struct static_array;// error: Values expands template type parameter
                                                      // pack T within the same template parameter list  

—结束示例]

关于整段,我对此有很多困惑。我将在下面列出我的困惑。

  1. 其类型包含一个或多个未扩展参数包的参数声明是包扩展。

    关于这句话,一个参数声明如何包含多个类型?Aparameter-declaration可以是类似T variableor的形式T... variable,第一个是简单的参数声明,第二个是一个参数包,可以接受多个相同类型的参数T,无论如何,它们只允许接受指定的相同类型的参数由T. 它说类型参数吗?似乎只有类型参数包可以接受不止一种差异类型。还是别的什么?这句话怎么读?

  2. 模板参数包是一个类型参数,其模板参数列表包含一个或多个未扩展的参数包是包扩展。

    这句话是指模板模板参数吗?似乎只有这种 template-parameter 可以有template-parameter-list,由于:

模板 < 模板参数列表 > 类型参数键 ...opt 标识符 opt

  1. 根据整个段落,我仍然无法理解为什么Dims不是包扩展而是Values ,根据这一段,什么可以是包扩展?似乎没有任何迹象表明它会像这样的形式,Something ...或者我在这句话中错过了吗?

如果我有什么误解。请纠正我。

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

解决方案


参数声明如何包含多个类型?参数声明可以是 likeT variable或的形式T... variable,第一个是简单的参数声明,第二个是可以接受多个相同类型的参数的参数包T,无论如何,它们只允许接受相同的参数指定的类型T

您缺少T参数包的情况。该示例列出了这个

template<class... T> struct value_holder {
  template<T... Values> struct apply { };             // Values is a non-type template parameter pack
                                                      // and a pack expansion
};

这里Values有不同的类型。我们正在扩展T定义Values,所以这是一个包扩展。Values是参数包,它的类型是T

根据整个段落,我仍然无法理解为什么Dims不是包扩展而是Values,根据这一段,什么可以是包扩展?似乎没有任何迹象表明它会像这样的形式,Something ...或者我在这句话中错过了吗?

您需要在可变参数模板定义中有一个模板。这就是为什么value_holder有一个内部结构apply,这一段是说你不能在一个模板中做到这一点,你需要嵌套它们。从例子

template<class... T, T... Values> struct static_array;// error: Values expands template type parameter
                                                      // pack T within the same template parameter list  

推荐阅读