cpp-ru / ideas

Идеи по улучшению языка C++ для обсуждения
https://cpp-ru.github.io/proposals
Creative Commons Zero v1.0 Universal
89 stars 0 forks source link

обобщить `rebind` в стандартной библиотеке #539

Open sigasigasiga opened 1 year ago

sigasigasiga commented 1 year ago

насколько мне известно, изначально для нужд стандартной библиотеки rebind был необходим только для аллокаторов. теперь, с грядущим приходом C++23 rebind будет необходим ещё и для std::expected.

как мне кажется, плодить для каждого нуждающегося в rebind'е класса отдельный typedef -- слишком кривое решение, которое мало того что плохо масштабируется, порождая лишний бойлерплейт, так ещё и выглядит просто ужасно (вспомните про std::allocator_traits<AllocatorForT>::template rebind_alloc<U>). хотя ничто не мешает реализовать подобный функционал вообще для всех шаблонов классов сразу

namespace detail {

template<typename...>
struct type_vector{};

template<template<class...> class T, typename... OldArgs, typename... NewArgs>
T<NewArgs...> rebind_impl(T<OldArgs...>&& f, type_vector<NewArgs...>);

} // namespace detail

template<typename Rebindee, typename... NewArgs>
struct rebind
{
    using type = decltype(rebind_impl(std::declval<Rebindee>(), detail::type_vector<NewArgs...>{}));
};

template<typename Rebindee, typename... NewArgs>
using rebind_t = typename rebind<Rebindee, NewArgs...>::type;

int main()
{
    std::allocator<int> int_alloc;
    rebind_t<decltype(int_alloc), double> double_alloc;
    static_assert(std::is_same_v<decltype(double_alloc), std::allocator<double>>);
}
kelbon commented 1 year ago

нуууу... Вообще-то мешает. Это не для всех шаблонов работает, а только для тех где типы. И зачем rebind exptected?? P.S. аллокатор просто должен зависеть не от типа, а от размера и алигмента