I think a utility function (as well as education materials) is useful in such cases. Modelling forward_like, probably something like:
template <typename T, typename U>
constexpr auto forward_pointer_like(U* ptr)
{
constexpr bool is_adding_const =
is_const_v<remove_reference_t<T>>;
if constexpr (is_const_v<remove_reference_t<T>> !=
is_adding_const) {
if constexpr (is_adding_const) {
return const_cast<const U*>(ptr);
} else {
return const_cast<remove_const_t<U>*>(ptr);
}
} else {
return ptr;
}
}
Related idea: Should we just update as_const to make it generate a const T* given a T*? This could be an easy fix that allows us to simply use forward_like, but I am not sure whether it can break things.