【问题标题】:Can I partially specialize a template with a pattern like foo<T..., int, U...>?我可以使用 foo<T..., int, U...> 之类的模式部分专门化模板吗?
【发布时间】:2012-06-17 17:37:38
【问题描述】:

如果可能的话,可以在不递归的情况下索引可变参数模板参数包。但是,GCC 在这里是refusing to pick up my partial specialization

template <int I, typename List>
struct element_impl;

template <typename... TL, int... IL, typename T, int I, typename... TR, int... IR>
struct element_impl<I, typelist<pair<TL,IL>..., pair<T,I>, pair<TR,IR>...>> {
    typedef T type;
};

prog.cpp:在 'element<0, typelist<int, double, char, float, long int> >' 的实例化中:
prog.cpp:52:34: 从这里实例化
prog.cpp:47:79: 错误:无效使用不完整类型'struct element_impl&lt;0, typelist&lt;pair&lt;int, 0&gt;, pair&lt;double, 1&gt;, pair&lt;char, 2&gt;, pair&lt;float, 3&gt;, pair&lt;long int, 4&gt; &gt;'

GCC 有问题,还是我忽略了可变参数模板的一些限制?

【问题讨论】:

  • 对于this simple code,GCC 说:error: parameter pack 'T' must be at the end of the template parameter list。所以我倾向于认为这是一种语言限制。
  • @Nawaz 那完全不一样。
  • 它并不“完全”相同,但错误消息非常清楚:参数包必须在模板参数列表的末尾。 GCC 也在这里重复同样的信息:ideone.com/2Rifn
  • @Nawaz 看来你是对的。 :(
  • @Nawaz 你有一个主模板。该限制不适用于部分专业化。

标签: c++ templates c++11 variadic-templates


【解决方案1】:

规范在 14.8.2.5p9 中说

如果 P 有一个包含&lt;T&gt;&lt;i&gt; 的形式,则相应模板参数列表P 的每个参数Pi 与@ 的相应模板参数列表的相应参数Ai 进行比较987654326@。如果P 的模板实参列表包含不是最后一个模板实参的包展开,则整个模板实参列表是非推导上下文。

不幸的是,您的 typelist&lt;T&gt; 与该模式匹配。

【讨论】:

  • 你能用简单的话详细说明标准的文本吗,可能有一两个例子?
  • @Nawaz @RMartinho 展示了这个规则的一个很好的例子,可能比我能想到的任何东西都要好。 &lt;T&gt; 表示“包含类型参数(包)的模板参数列表”,“”表示“包含非类型参数(包)的模板参数列表”。
【解决方案2】:

AFAICT,匹配偏特化的规则与函数参数的规则类型推导相同。 §14.8.2.1/1 说如下:

对于出现在末尾的函数参数包 parameter-declaration-list,每个剩余参数的类型A 该调用与 declarator-id 的类型 P 进行比较 函数参数包。每个比较推导出模板参数 对于模板参数包中的后续位置,扩展为 函数参数包。对于一个函数参数包 不会出现在 parameter-declaration-list 的末尾,类型 参数包是非推导上下文。

所以在这种情况下不能推导出包TLIL,也不选择偏特化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-08
    • 2023-04-08
    • 1970-01-01
    • 2015-04-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多