https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80667
--- Comment #1 from Ed Catmur <ed at catmur dot co.uk> --- note: the rationale for using std::integral_constant rather than a T non-type argument is CWG 1315. Clang rejects in -std=c++1z: <source>:22:63: error: ambiguous partial specializations of 'Impl<unsigned char, std::integral_constant<unsigned char, '\x00'> >' Impl<unsigned char, std::integral_constant<unsigned char, 0>> foo() ^ <source>:13:8: note: partial specialization matches [with T = unsigned char, MaxValue = '\x00'] struct Impl<T, std::integral_constant<T, MaxValue>> ^ <source>:18:8: note: partial specialization matches [with T = unsigned char] struct Impl<T, std::integral_constant<T, traits<T>::const_min>> ^ 1 error generated. In -std=c++14 gcc and clang both accept, and agree on using the latter partial specialization. I'm not clear whether the code should be rejected in -std=c++1z, or why the behavior of the compilers is any different. Performing the transformation in temp.class.order, gcc rejects as ambiguous in -std=c++14, and ICEs in -std=c++1z; clang rejects as ambiguous in -std=c++14, and selects the *former* specialization in -std=c++1z.