别名模板,部分专业化和无效的参数类型void [英] Alias template, partial specialization and the invalid parameter type 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
的未命名参数组成的参数列表等效于空参数列表.除这种特殊情况外,参数的类型不得为 cvvoid
.
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 cvvoid
.
在这种情况下,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 ofvoid
, 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屋!