Date: Fri, 18 Mar 2022 18:03:31 +0000
Hi, I was wondering if it would make sense to add deduced "this" to already-existing CRTP interfaces, such as std::ranges::view_interface. I was thinking for instance it could be changed to
template<typename Derived = void>
struct view_interface {
/* ... */
};
where for all now-existing uses of view_interface it would function as normal, with the inheriting class specified in the template instantiation, but new classes could do e.g.
template</* Potentially several lengthy template parameters */>
struct my_view : std::ranges::view_interface<> {
/* ... */
};
which would instantiate std::ranges::view_interface<void> which would take advantage of the new deduced "this" pattern, cutting down on code duplication and over-verbosity.
I don't think this would be an API-breaking change, and I'm pretty sure this wouldn't be ABI-breaking either since no one should have instantiated a std::ranges::view_interface<void>, but even if they did then they wouldn't be able to really do anything with it.
This change though would increase the number of views with a shared parent class (std::ranges::view_interface<void>) which might stop space optimizations because two objects of the same type can't share the same space, even with [[no_unique_address]] (at least as I understand it). I personally don't find that to be a compelling counterargument though, especially with std::ranges::view_base already existing.
But then there's also that the deduced "this" pattern could deduce a class that derives from "my_view" from the earlier example, which seems like a thing to keep in mind for any instance of using deduced "this" in a CRTP way, but still the question remains of is that a problem, and if so, is it enough to outweigh the benefits of this change? I personally am not sure.
I would love to hear others' input on this idea, thank you in advance.
template<typename Derived = void>
struct view_interface {
/* ... */
};
where for all now-existing uses of view_interface it would function as normal, with the inheriting class specified in the template instantiation, but new classes could do e.g.
template</* Potentially several lengthy template parameters */>
struct my_view : std::ranges::view_interface<> {
/* ... */
};
which would instantiate std::ranges::view_interface<void> which would take advantage of the new deduced "this" pattern, cutting down on code duplication and over-verbosity.
I don't think this would be an API-breaking change, and I'm pretty sure this wouldn't be ABI-breaking either since no one should have instantiated a std::ranges::view_interface<void>, but even if they did then they wouldn't be able to really do anything with it.
This change though would increase the number of views with a shared parent class (std::ranges::view_interface<void>) which might stop space optimizations because two objects of the same type can't share the same space, even with [[no_unique_address]] (at least as I understand it). I personally don't find that to be a compelling counterargument though, especially with std::ranges::view_base already existing.
But then there's also that the deduced "this" pattern could deduce a class that derives from "my_view" from the earlier example, which seems like a thing to keep in mind for any instance of using deduced "this" in a CRTP way, but still the question remains of is that a problem, and if so, is it enough to outweigh the benefits of this change? I personally am not sure.
I would love to hear others' input on this idea, thank you in advance.
Received on 2022-03-18 18:03:37