struct A{ constexpr A(double const& rf){} }; template<class T, T B> struct C{}; int main() { C<A,0> b; } This code is accepted by GCC while rejected by Clang. [temp.arg.nontype] p2 > A template-argument for a non-type template-parameter shall be a converted constant expression ([expr.const]) of the type of the template-parameter. From a prvalue of type `int` to type `A`, the user-defined conversion sequence will involve floating-integral conversions that are not permitted in [expr.const] p10. GCC should reject this example.
There are two issues here really (both accepts invalid). First is binding to a temp is invalid: struct A{ constexpr A(double const &rf){} }; template<class T, T B> struct C{}; int main() { C<A,0.> b; } ----- CUT ---- Second is the conversion is also invalid: struct A{ constexpr A(double rf){} }; template<class T, T B> struct C{}; int main() { C<A,0> b; }
bind the temporary is permitted here to me. Since the template parameter is not a reference type, there is no restriction on whether a temporary object is generated in the implicit conversion.