【问题标题】:How can a template parameter pack have other trailing arguments?模板参数包如何有其他尾随参数?
【发布时间】:2019-02-10 00:20:50
【问题描述】:

在 C++14 草案标准中,[temp.param]/11 说:

如果是主类模板或别名模板的模板参数 是一个模板参数包,它应该是最后一个模板参数。

如果您尝试编译以下模板,那么编译器会报错。

template< typename ...Args, void(*f)(Args...) > // ERROR
struct Bar
{};

但是在这种情况下它是如何工作的呢?

template< typename F, F >
struct Bar;

template< typename ...Args, void(*f)(Args...) > // OK ???
struct Bar< void(*)(Args...), f >
{};

我可以看到它与作为专业化类模板的一部分有关,但是为什么

规则明确指出它适用于 primary 类模板。这是否意味着专业化规则会发生变化?

我试图在标准中搜索这个,但找不到任何东西。能否请您对此有所启发。

【问题讨论】:

  • 我相信有人会想出更详细的答案,但这主要是你已经得到的:模板特化既不是主类模板也不是别名模板。

标签: c++ templates c++14 variadic


【解决方案1】:

该规则明确指出它适用于主类模板。这是否意味着专业化规则会发生变化?

是的。很简单,因为专业化不是主要的类模板。因此,如果该措辞旨在适用于 all 模板声明,它会这样说。相反,该规则仅适用于主要类模板(...和别名模板,不能专门化)。专业没有这样的限制。

这基本上是因为在主模板中的模板参数包之后不可能提供任何模板参数,但在专业化中绝对可以这样做。例如,这是连接两个 tuple 特化的一种方法:

template <typename T, typename U>
struct tuple_concat;

template <typename... Ts, typename... Us> // <== parameter pack *after* parameter pack
struct tuple_concat<tuple<Ts...>, tuple<Us...>> {
    using type = tuple<Ts..., Us...>;
};

这很好,它有效,它很有用。但是, 能够在主类/变量/别名模板中编写这样的东西并没有任何好处 - 所以为了简单起见,禁止这样做。


与所有的 C++ 一样,当然有一个脚注。您本可以提供用于触发替换失败的尾随默认模板参数。但是还有其他方法可以解决这个问题,然后我们很快就会有概念。

【讨论】:

  • 非常感谢您的回答。我现在明白为什么它是有效的 C++ 代码了。但是,不应该在标准的某处指定吗?如果我错过了,请您指出正确的方向。在你的例子中,你不会像这样创建一个 tuple_concat 对象: tuple_concat<:tuple>,std::tuple > foo; 如果是这样,那么为什么你需要那种专业化?仅仅拥有主模板同样有效。对不起,我现在对它的用法还是有点模糊。顺便说一句,我认为您在专业化类名称上犯了拼写错误 - tuple_cat。
  • @Constantinos 并非所有内容都需要明确说明......否则标准将具有无限长度。重点不是要创建一个tuple_concat 对象,重点是tuple_concat&lt;tuple&lt;int,long&gt;,tuple&lt;char,bool&gt;&gt;::typetuple&lt;int,long,char,bool&gt;...对于这个任务,主节点不能“同样好”地工作。
  • "...然后我们很快就会有概念"。我已经听说了 10 多年了!希望你是对的!
  • @Barry:很公平,但我相信这样的东西应该在标准中表达出来——至少要提一下。理想情况下,他们还会用几句话解释为什么允许将其作为专业化的一部分的原因。我现在明白它是有效的......但为什么呢?让他们决定允许它的专业化有什么特别之处?仅仅是简单还是又一个“特殊规则”?为众多问题道歉 - 我确实喜欢揭开这些东西的面纱。
  • @ConstantinosGlynos 该标准不是教程。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-07
  • 1970-01-01
  • 1970-01-01
  • 2018-01-13
  • 2016-12-02
  • 1970-01-01
相关资源
最近更新 更多