What I tell below (under OLD POST) should be true to a degree, but the actual problem with this is, that SFINAE is used wrongly, hence I am not that sure anymore that this is a bug in gcc.
An alias declaration must always succeed, you cannot SFINAE there, since it is not a class or function declaration or specializations (that makes sense, since you cannot specialize aliases). If the alias declaration does not succeed, the programm is ill-formed. Hence the compiler may assume that it will never come to the case that the alias declaration does not succeed until you force it to instantiate such a template.
Hence it is perfectly acceptable for the compiler to think that sfinae_v_t<T,...>
is always T
, since that will happen, when the programm is not ill-formed. Hence it will see, that in all cases in which the programm is not ill-formed, the partial specialization does not specialize and as such it will tell you that this is ill-formed. (That is what clang does).
I don't think that the compiler is forced to do this. And if it does not, and just thinks "Ok, sfinae_v_t
is some type, whatever.", then it is not obvious that this a redeclaration. So I think until we instantiate one of them there is nothing wrong with not throwing an error.
But when we instantiate it there should be either the problem that we have a redeclaration or that the program is ill-formed due to std::enable_if
, depending on the template argument. GCC should pick up at least one of them but does neither.
This also does absolutely not apply to the more easy example without std::enable_if
. So I still think this is a bug in GCC, but I am sufficiently mindfucked that I cannot say that with certainity anymore. I would just say, someone should report that as a bug and let the people from gcc think about it.
OLD POST
This is a bug in gcc. The standard gives us rules for converting a class template in function templates. One class template is more specialized than another if its function comes before the other's in the partial function template ordering.
I created the functions here and now gcc claims that calling them is ambiguous, hence it would also have to say that the class templates are equally specified.
Note: Reading the standard carefully, the compiler in my head agrees with clang.