别名模板,部分专业化和无效的参数类型void [英] Alias template, partial specialization and the invalid parameter type void

查看:163
本文介绍了别名模板,部分专业化和无效的参数类型void的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下代码:

template<typename F>
struct S;

template<typename Ret, typename... Args>
struct S<Ret(Args...)> { };

template<typename... Args>
using Alias = S<void(Args...)>;

int main() {
    S<void(int)> s;
    Alias<int> alias;
}

它可以正常工作,正如预期的那样,涉及S的行和涉及Alias的行都在引擎盖下定义了相同的类型S<void(int)>.

It works fine, as expected and both the line involving S and the one involving Alias define under the hood the same type S<void(int)>.

现在,请考虑以下更改:

Now, consider the following changes:

int main() {
    S<void(void)> s;  // this line compiles
    Alias<void> alias;  // this line does not
}

出于与上述类似的原因,我希望它可以进行编译.
不用说,由于涉及Alias的行,它无法编译,相反,我得到了错误:

I expected it to compile, for reasons that are similar to the ones above mentioned.
It goes without saying that it doesn't compile because of the line involving Alias, instead I get the error:

替代使用Alias = S [with Args = {void}]的模板"

In substitution of 'template using Alias = S [with Args = {void}]'

[...]

错误:参数类型无效'void'

error: invalid parameter type 'void'

问题很简单:我在这里错过了什么?

The question is pretty simple: what I missed here?

推荐答案

摘自[dcl.fct],

From [dcl.fct], emphasis mine:

由单个非依赖类型void的未命名参数组成的参数列表等效于空参数列表.除这种特殊情况外,参数的类型不得为 cv void.

A parameter list consisting of a single unnamed parameter of non-dependent type void is equivalent to an empty parameter list. Except for this special case, a parameter shall not have type cv void.

在这种情况下,Args...是从属类型包,因此不允许在其中使用void.在[temp.deduct]的注释中重复了这个想法:

In this case, Args... is a dependent type pack, so void is not allowed there. This idea is repeated in a note in [temp.deduct]:

[注意:类型推断可能由于以下原因而失败:
— [...]
—尝试创建函数类型,其中参数的类型为void,或者返回 type是函数类型或数组类型.
— [...]
-尾注]

[ Note: Type deduction may fail for the following reasons:
— [...]
— Attempting to create a function type in which a parameter has a type of void, or in which the return type is a function type or array type.
— [...]
—end note ]

请注意,S<void(void)>会进行编译,因为void(void)是非依赖的,并且等效于void(),因此,永远不会推论Ret(Args...)在参数列表中包含void-推论出Args...为空.

Note that S<void(void)> compiles since void(void) is non-dependent and is equivalent to void(), so Ret(Args...) is never deduced to have void in the parameter list - it's deduced with Args... empty.

至少有一个简单的解决方法,您只需编写Alias<>.

At least there's a simple workaround in that you can just write Alias<>.

这篇关于别名模板,部分专业化和无效的参数类型void的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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