On Sun, 2 May 2021 at 17:56, Arthur O'Dwyer via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
However, I don't see any need to standardize is_same_uncvref; it seems trivial to write by hand.
Notice I could also have done
    requires (not same_as<remove_cvref_t<T>, AlphableRef>)
which is almost as short.

This problem often comes up when writing variadic forwarding constructors, for which writing the test is a bit of a pain. 

One idiom is to use same_as with function types, which works but is a bit of a head-scratcher the first time one sees it:

     template<class... T>
        requires (not same_as<A(A), A(remove_cvref_t<T>...)>)
        explicit(sizeof...(T) == 1u)
    A(T&&... t) { ... }

Or as an alternative, only possible since C++20 (for short-circuiting constraint evaluation) and with very fragile syntax:

     template<class... T>
        requires (sizeof...(T) != 1u or not same_as<A, remove_cvref_t<T>...>)
        explicit(sizeof...(T) == 1u)
    A(T&&... t) { ... }

Being able to replace this with `requires non_copy_constructor_args_v<A, T...>` could well improve readability.

Note that this solution would work equally well in the single-argument case, although a 2-parameter concept (with reversed arguments) could also be useful for writing converting constructor templates:

    template<non_copy_constructor_arg<A> T>
    A(T&& t) { ... }