Reputation: 50550
This question is a follow-up of another question.
Consider the following code:
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)
}
If we comment out (2), the example complies, otherwise the compilation fails.
From the linked question we find that (2) fails because:
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 typecv void.
Moreover:
[ 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 ]
What's not clear to me is why (1) compiles.
In other terms, if (2) fails because Args
is a dependent type and suffers from the above mentioned limitation in:
template<typename... Args>
using Alias = S<void(Args...)>;
The same problem should affect Args
in:
template<typename Ret, typename... Args>
struct S<Ret(Args...)> { };
Why is it fine using void
as S<void(void)>
in this case?
Note that the rush is towards the std::function
that accepts as well this kind of signature.
Upvotes: 0
Views: 58