这个问题是另一个问题的后续问题。
考虑以下代码:
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(void)> s; // (1)
Alias<void> alias; // (2)
}
如果我们注释掉(2),则示例符合,否则编译失败。
从链接的问题中,我们发现(2)失败,因为:
由非依赖类型 void 的单个未命名参数组成的参数列表等效于空参数列表。除此特殊情况外,参数不应具有 typecv void。
而且:
[注意:类型推导可能因以下原因而失败: — [...] — 尝试创建参数类型为 void 或返回类型为函数类型或数组类型的函数类型。— [...] — 尾注]
我不清楚为什么(1)编译。
换句话说,如果(2)失败,因为Args
它是依赖类型并且受到上述限制:
template<typename... Args>
using Alias = S<void(Args...)>;
同样的问题应该影响Args
:
template<typename Ret, typename... Args>
struct S<Ret(Args...)> { };
为什么在这种情况下使用void
as很好S<void(void)>
?
请注意,急于std::function
接受这种签名的人。