http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59056
--- Comment #7 from Walter Mascarenhas <walter.mascarenhas at gmail dot com> --- In itself, Richard's paragraph "Morally, the function should ambiguous... " implies that the code below is ambiguous. However, it compiles just fine with gcc 4.8.1, because gcc also takes into account the information that check< Foo<int> >() is false in order to discard the specialization with the enable_if. In other words, the X in check<X> is not completely arbitrary, it my be related to Foo<T>. I find it odd that in the code below gcc uses the information that check< Foo<int> >() is false and in the first version it neglects the equivalent information that check< Foo<int> >() is true. Of course, the standard has the last word on these things, but not everything in it is "morally" obvious or completely logical. Here is the modified code (I only changed the value returned by check from true to false): template <class X> constexpr bool check() { return false; } template <class X, class Enable = void> struct Bar {}; template <class X> struct Bar<X, typename std::enable_if< check<X>() >::type> {}; template <class T> struct Bar< Foo<T> > {}; void instance() { Bar< Foo<int>, void > av; } On Wed, Nov 13, 2013 at 7:00 PM, richard-gccbugzilla at metafoo dot co.uk < gcc-bugzi...@gcc.gnu.org> wrote: > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59056 > > --- Comment #5 from Richard Smith <richard-gccbugzilla at metafoo dot > co.uk> --- > (In reply to Jonathan Wakely from comment #2) > > I thought if the partial specializations were ambiguous then these > function > > overloads should be too. > > Yes, this inconsistency is very surprising. GCC, EDG, and Clang all behave > the > same way, and yet I can find no justification for this behavior in the > standard. > > Morally, the function call should be ambiguous. The first 'func' takes > Bar<X> > for any X where check<X>() is true, and the second 'func' takes Bar<X> for > any > X that matches Foo<T>. Neither of those constraints implies the other, so > the > call should be ambiguous. > > In Clang's case, the problem is that we fail to enforce > [temp.deduct.type](14.8.2.5)/1 when partially ordering function templates > -- we > don't check that deduction actually succeeded in finding types that make > 'A' > match the 'deduced A' -- but we do check that when partially ordering class > templates, and we don't spot the problem earlier because the > enable_if<...> is > a non-deduced context. I expect EDG and GCC have a similar bug. > > -- > You are receiving this mail because: > You reported the bug. >