模板参数包如何具有其他尾随参数? [英] How can a template parameter pack have other trailing arguments?

查看:54
本文介绍了模板参数包如何具有其他尾随参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In the C++14 draft standard, [temp.param]/11 says:


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

If a template-parameter of a primary class template or alias template is a template parameter pack, it shall be the last template-parameter.

如果尝试编译以下模板,则编译器会抱怨。

If you try compiling the following template, then the compiler will complain.

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

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

But how does it work in this case?

template< typename F, F >
struct Bar;

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

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

I can see that it has something to do with it being part of the specialization class template, but why?

该规则明确指出它适用于 primary 类模板。

The rule clearly states that it applies to a primary class template. Does this mean that the rules change for specializations?

我试图在标准中搜索此规则,但找不到任何东西。

I tried to search for this in the standard, but couldn't find anything. Can you please shine some light into this.

推荐答案


该规则明确指出它适用于小学班级模板。这是否意味着规则会因专业而改变?

The rule clearly states that it applies to a primary class template. Does this mean that the rules change for specializations?

是。完全是因为专业化不是主类模板。因此,如果该措辞旨在适用于 all 模板声明,则应这样说。相反,该规则非常打算仅适用于主类模板(...和别名模板,它们不能专门化)。

Yes. Quite simply because a specialization is not a primary class template. So if the wording was intended to apply to all template declarations, it would say so. Instead, the rule is very much intended to only apply to the primary class template (... and alias templates, which cannot be specialized). There is no such restriction for specializations.

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

This is fundamentally because it is not possible to provide any template arguments after a template parameter pack in the primary template, but it is definitely possible to do so in specializations. For instance, here's one way to concatenate two tuple specializations:

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...>;
};

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

This is fine, it works, it's useful. But there's no benefit from being able to write stuff like this in a primary class/variable/alias template - so it's forbidden for simplicity.

与C ++一样,当然也有脚注。您可能已经能够提供用于触发替换失败的尾随默认模板参数。但是,您可以通过其他方法解决该问题,然后无论如何我们很快就会有Concepts。

As with all things C++, there is of course a footnote. You could have been able to provide a trailing defaulted template parameter that is used to trigger a substitution failure. But there are other ways you can go about solving that problem, and then we'll have Concepts soon anyway.

这篇关于模板参数包如何具有其他尾随参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆