Deducing a partial specialization fails

Please consider the example here:

https://godbolt.org/z/4AwrXz

Clang up to version 3.9.1 and all recent versions of other compilers accept the code. Clang version >=4.0 fails.
If you move the definition of AccessorPointersT to Foo, it works again and the partial specialization is deduced correctly.
Is this a bug or a pedantic interpretation of the c++ standard by clang?

Best Olaf

Please consider the example here:

https://godbolt.org/z/4AwrXz

Clang up to version 3.9.1 and all recent versions of other compilers accept the code. Clang version >=4.0 fails.
If you move the definition of AccessorPointersT to Foo, it works again and the partial specialization is deduced correctly.
Is this a bug or a pedantic interpretation of the c++ standard by clang?

I am guessing it is a bug having to do with the template from whose specialization’s arguments we should deduce from being dependent.

Well, the compiler appears to be right that the partial specialization is unreachable because the IsConst parameter can’t be deduced.
Suppose you instantiated Foo<A>, where A was a class type defined as

struct A {};
template<> struct Bar {
template using AccessorPointersT = int;
};

Then Foo<A>::AccessorPointersT<false> and Foo<A>::AccessorPointersT<true> denote the same type (namely, int). So you can’t use template “pattern matching” to differentiate them, because they’re identical.

(Would you expect the partial specialization to be chosen in this case? If so, what would you expect it to deduce for the actual value of IsConst?)

If you move the definition of the AccessorPointers struct from Bar down into Foo, then I believe the problem goes away, as you indicate. In that case, Foo<A>::AccessorPointersT<false> and Foo<A>::AccessorPointersT<true> definitely denote different types, and so it’s OK to use pattern matching on them.

–Arthur

Instantiating Foo for the above A would be ill-formed. But Foo itself is not, because it has valid instantiations (eg, Foo).

It looks like we fail to properly take the deduction depth into account when checking for deducibility of a dependent template specialization type, and incorrectly treat all dependent-scope template specialization types as non-deducible (rather than being “dependently deducible”). :frowning: