On Mon, May 27, 2024 at 4:50 PM Frederick Virchanza Gotham via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
On Mon, May 27, 2024 at 4:04 PM Gašper Ažman wrote
>
> strongly against a baseclass. The reason anyone would use anything but
> std::elide is because they have their own, and changing that is
> difficult.
>
> Request a `bool std::is_elider_v<my-class>` specialization and then
> have `template <typename X> concept elider =  std::is_elider_v<remove_cvref_t<X>>`.

I think that's more complicated than just having:

    class elide {
    public:
        typedef true_type tag_elide;
    };

Plus, my strategy has the added versatility of being able to override
it in a derived class with "false" instead of "true":

    class MyElide : public std::elide {
    public:
        typedef std::false_type tag_elide;
    };

I agree that Gašper's suggestion of an ad-hoc free-floating `is_foo_v`/`is_foo` variable/class template is not optimal. C++20 Ranges ended up with a soup of free-floating templates of that form — some variable templates, some class templates — and it's just icky.
A member typedef is generally the way to go. However, in any member-typedef-based design that's intended for a widely reusable library, I strongly recommend the pattern
    struct MyT {
      using is_library3_thing = MyT;  // as seen in libc++'s __trivially_relocatable
    };
    template<class X> concept library3_thing = std::is_same_v<typename X::is_library3_thing, X>;
rather than either of the state-of-the-art approaches
    struct MyT {
      using is_library1_thing = void;  // as seen in C++14's is_transparent
      using is_library2_thing = true_type;  // as seen in C++11's propagate_on_container_copy_assignment
    };
    template<class X> concept library1_thing = requires { typename X::is_library1_thing; };
    template<class X> concept library2_thing = X::is_library2_thing::value;
The reason is inheritance.
    struct MyU : public MyT {};
If `MyU` inherits from `MyT`, then it is_library1_thing by definition and there's no way to change that.
It's also is_library2_thing by default, unless the author of `MyU` has the presence of mind to define `using is_library2_thing = false_type;` in the body of `MyU`.
But it's not is_library3_thing by default. You have to re-opt-in to `is_library3_thing` at each level of inheritance (that is, at each leaf). This is what you want for most traity things, and I think it's what you'd want for your `elide` thingie, too. (Mind you, I don't think your `elide` thingie makes enough sense to say anything really concrete about what it "should" be like.)

–Arthur