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