On Mon, Oct 10, 2022 at 8:09 AM Patrick Palka via Libstdc++ <libstd...@gcc.gnu.org> wrote: > > On Mon, 10 Oct 2022, Jonathan Wakely via Libstdc++ wrote: > > > Tested powerpc64le-linux. Pushed to trunk. > > > > -- >8 -- > > > > Currently we only reject std::make_signed_t<bool> but not cv bool. > > Similarly for std::make_unsigned_t<cv bool>. > > > > As well as making those ill-formed, this adds a requires-clause to the > > make_signed and make_unsigned primary templates. This makes > > non-integral, non-enum cases fail immediately with a clear error, rather > > than giving an error about __make_signed_selector<T, false, false> being > > incomplete. > > IIUC the requires-clause turns what was once a hard error into a SFINAE > error, so e.g. for > > template<class T> typename make_signed<T>::type f(int); > template<class T> void f(...); > int main() { f<void>(0); } > > the call to f would previously be rejected due to an error outside the > immediate context about incomplete __make_signed_selector, and now with > the requires-clause resolves to the second overload. I wonder if this > new behavior is conforming -- the examples in [structure.specifications] > of how to implement 'Mandates' suggest that a failed 'Mandates' should > yield a hard error?
I'm also concerned about the inability to name make_signed<X> in a context that doesn't require its instantiation (e.g., conditional_t<is_integral_v<T>, make_signed<T>, type_identity<T>>::type). That seems a plausible use case, and breaking it doesn't seem great to me (conformance aside).