模板参数包如何具有其他尾随参数?

How can a template parameter pack have other trailing arguments?

提问人:Constantinos Glynos 提问时间:9/5/2018 最后编辑:BarryConstantinos Glynos 更新时间:9/5/2018 访问量:240

问:

在 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 >
{};

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

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

我试图在标准中搜索这个,但找不到任何东西。你能不能对此有所了解。

C++ 模板 C++14 可变参数

评论

0赞 Not a real meerkat 9/5/2018
我相信有人会想出更详细的答案,但这主要是你已经得到的:模板专用化既不是主类模板,也不是别名模板。

答:

3赞 Barry 9/5/2018 #1

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

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

这从根本上说是因为不可能在主模板中的模板参数包之后提供任何模板参数,但在专业化中绝对可以这样做。例如,以下是连接两个专业化的一种方法: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++ 一样,当然有一个脚注。您可能已经能够提供用于触发替换失败的尾随默认模板参数。但是,还有其他方法可以解决这个问题,然后我们很快就会有概念画板。

评论

0赞 Constantinos Glynos 9/5/2018
非常感谢您的回答。我现在明白为什么它是有效的 C++ 代码了。但是,它不应该在标准的某个地方指定吗?如果我错过了,你能不能给我指出正确的方向。在您的示例中,您不会像这样创建一个tuple_concat对象: tuple_concat<std::tuple<int,long>,std::tuple<char,bool> > foo;如果是这样,那你为什么需要这种专业化呢?仅拥有主模板同样有效。对不起,我现在对它的用法仍然有点模糊。顺便说一句,我认为您在专业化类名称上犯了拼写错误 - tuple_cat。
1赞 Barry 9/5/2018
@Constantinos 并非所有事情都需要明确说明......否则,标准将具有无限长。重点不在于创建一个对象,关键是......对于此任务,主服务器的工作效果并不“同样好”。tuple_concattuple_concat<tuple<int,long>,tuple<char,bool>>::typetuple<int,long,char,bool>
0赞 Klaus 9/5/2018
"...然后我们很快就会有概念画板”。我听说这句话已经有10多年了!希望你是对的!
0赞 Constantinos Glynos 9/6/2018
@Barry:很公平,但我认为这样的事情应该在标准中表达——至少是提及。理想情况下,他们还会用几句话解释为什么允许将其作为专业化的一部分的原因。我现在明白它是有效的......但是为什么?专业化有什么特别之处,让他们决定允许它?这仅仅是简单,还是又一个“特殊规则”?对于众多问题,我深表歉意 - 我确实喜欢在这些事情上揭开引擎盖。
0赞 Barry 9/6/2018
@ConstantinosGlynos 标准不是教程。