参数包必须位于参数列表的末尾...什么时候以及为什么? [英] Parameter pack must be at the end of the parameter list... When and why?

查看:182
本文介绍了参数包必须位于参数列表的末尾...什么时候以及为什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果参数包绑定到类,我不知道参数包必须位于参数列表末尾的原因,而如果参数列表是成员方法声明的一部分,则放宽约束。

I don't get the reason for which a parameter pack must be at the end of the parameter list if the latter is bound to a class, while the constraint is relaxed if the parameter list is part of a member method declaration.

换句话说,这是编译的:

In other terms, this one compiles:

class C {
    template<typename T, typename... Args, typename S>
    void fn() { }
};

以下项没有:

template<typename T, typename... Args, typename S>
class C { };

为什么第一种情况是正确的而第二种情况却不正确?

我的意思是,如果这是合法的语法,在两种情况下都不应该吗?

Why is the first case considered right and the second one is not?
I mean, if it's legal syntax, shouldn't it be in both the cases?

要清楚地说明,真正的问题是我正在定义一个类似于以下内容的类

To be clear, the real problem is that I was defining a class similar to the following one:

template<typename T, typename... Args, typename Allocator>
class C { };

将分配器类型作为最后一个类型将是值得赞赏的,但是我可以以某种方式解决它(无论如何) ,如果您的建议值得赞赏,也许您的建议比我的要优雅得多!)。

就是说,我得到了一个错误:

Having the allocator type as the last type would be appreciated, but I can work around it somehow (anyway, if you have a suggestion it's appreciated, maybe yours are far more elegant than mine!!).
That said, I got the error:

参数包'Args'必须在模板参数列表的末尾

parameter pack 'Args' must be at the end of the template parameter list

只是很好奇要完全理解为什么在某些情况下会接受它,但在某些情况下却不接受。

So, I was just curious to fully understand why it's accepted in some cases, but it is not in some others.

此处是一个类似的问题,但它只是简单地解释了如何解决该问题,这对我来说很清楚。

Here is a similar question, but it simply explains how to solve the problem and that was quite clear to me.

推荐答案

它对函数模板有效,但仅当参数存在时推论可以帮助编译器解析模板参数,因为它代表您的函数模板示例为v

It is valid for function templates but only when argument deduction can help the compiler resolve the template parameters, as it stands your function template example is virtually useless because

template<typename T, typename... Args, typename S> void fn() { }
int main() { fn<int, int, int>(); }





test.cpp: In function 'int main()':
test.cpp:2:32: error: no matching function for call to 'fn()'
 int main() { fn<int, int, int>(); }
                                ^
test.cpp:1:57: note: candidate: template<class T, class ... Args, class S> void fn()
 template<typename T, typename... Args, typename S> void fn() { }
                                                         ^
test.cpp:1:57: note:   template argument deduction/substitution failed:
test.cpp:2:32: note:   couldn't deduce template parameter 'S'
 int main() { fn<int, int, int>(); }

编译器无法确定哪些模板参数属于参数包,而哪些 S 。实际上是@ T.C。指出它实际上应该是语法错误,因为无法实例化以这种方式定义的功能模板。

the compiler has no way of determining which template parameters belong to the parameter pack, and which to S. In fact as @T.C. points out it should actually be a syntax error because a function template defined in this manner cannot ever be instantiated.

更有用的功能模板将类似于

A more useful function template would be something like

template<typename T, typename... Args, typename S> void fn(S s) { }

因为现在编译器可以明确地匹配函数参数<模板类型为 S 的code> s ,其副作用为 S 将总是被推导-在第一个参数之后的所有显式模板参数都将属于 Args

as now the compiler is able to unambiguously match the function parameter s with the template type S, with the side effect that S will always be deduced - all explicit template parameters after the first will belong to Args.

这些都不适用于(主)类模板,不会推导参数,并且明确禁止使用以下参数:

None of this works for (primary) class templates, parameters aren't deduced and it's expressly forbidden:

来自n4567草案

http:// www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4567.pdf

[temp.param] / 11

[temp.param] / 11


[...]如果是主类模板或别名
模板的 template-parameter 是模板参数包,应为最后的
template-parameter 。[...]

[...]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 they were deduced it would be ambiguous as in the function template example).

这篇关于参数包必须位于参数列表的末尾...什么时候以及为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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