Информация об изменениях

Сообщение Re: template (синтаксис) больше не нужен? от 04.11.2023 22:02

Изменено 04.11.2023 22:05 Кодт

Re: template (синтаксис) больше не нужен?
Здравствуйте, johny5, Вы писали:

J>Есть ли какие то примеры, которые ещё нельзя переписать целиком, используя новый синтаксис? Что вы думаете?


Очевидно, когда параметр шаблона не выводится из аргументов.
Например, когда он относится к результату.
template<class T> T& get(auto& var) requires is_variant<decltype((var))> { ..... }

template<size_t N> auto& get(auto& tpl) requires is_std_tuple<decltype((tpl))> { ..... }


Или когда нужно вытащить параметры шаблона из типа аргумента.
Особенно, вариадики.
Например, идиома с индексами (да, понятно, что это лютый костыль, и неплохо бы в будущем от него избавиться)
template<size_t... Ns> void do_something_with_all_elements(auto& tpl, std::index_sequence<Ns...>) {
  ( do_something(std::get<Ns>(tpl)) , ... );
}

void do_something_with_all_elements(auto& tpl) {
  do_something_with_all_elements(tpl, std::make_index_sequence<std::tuple_size<decltype((tpl))>());
}


Для не-вариадиков, положим, можно написать метафункции (всё равно это будет ад-хок)
template<class L, class R> struct cons {};
struct nil {};

template<class> struct cons_traits {
  static constexpr bool value = false;
};
template<class L, class R> struct cons_traits<cons<L,R>> {
  static constexpr bool value = true;
  using left = L;
  using right = R;
};
template<class C> static constexpr bool is_cons_v = cons_traits<C>::value;
template<class C> using left_t = cons_traits<C>::left;
template<class C> using right_t = cons_traits<C>::right;

// и уже по месту - никаких template...

void do_something_with_list(auto l) {
  using C = decltype((l));
  if constexpr (is_cons_v<C>) {
    using L = left_t<C>;
    using R = right_t<C>;
    .....
  } else {
    .....
  }
}


Ну или же ограничить использование вариадиков, например, стандартным std::tuple и расшивать его с помощью std::apply.
Re: template (синтаксис) больше не нужен?
Здравствуйте, johny5, Вы писали:

J>Есть ли какие то примеры, которые ещё нельзя переписать целиком, используя новый синтаксис? Что вы думаете?


Очевидно, когда параметр шаблона не выводится из аргументов.
Например, когда он относится к результату.
template<class T> T& get(auto& var) requires (is_some_variant_v<decltype((var))>) { ..... }

template<size_t N> auto& get(auto& tpl) requires (is_some_tuple_v<decltype((tpl))>) { ..... }


Или когда нужно вытащить параметры шаблона из типа аргумента.
Особенно, вариадики.
Например, идиома с индексами (да, понятно, что это лютый костыль, и неплохо бы в будущем от него избавиться)
template<size_t... Ns> void do_something_with_all_elements(auto& tpl, std::index_sequence<Ns...>) {
  ( do_something(std::get<Ns>(tpl)) , ... );
}

void do_something_with_all_elements(auto& tpl) {
  do_something_with_all_elements(tpl, std::make_index_sequence<std::tuple_size<decltype((tpl))>());
}


Для не-вариадиков, положим, можно написать метафункции (всё равно это будет ад-хок)
template<class L, class R> struct cons {};
struct nil {};

template<class> struct cons_traits {
  static constexpr bool value = false;
};
template<class L, class R> struct cons_traits<cons<L,R>> {
  static constexpr bool value = true;
  using left = L;
  using right = R;
};
template<class C> static constexpr bool is_cons_v = cons_traits<C>::value;
template<class C> using left_t = cons_traits<C>::left;
template<class C> using right_t = cons_traits<C>::right;

// и уже по месту - никаких template...

void do_something_with_list(auto l) {
  using C = decltype((l));
  if constexpr (is_cons_v<C>) {
    using L = left_t<C>;
    using R = right_t<C>;
    .....
  } else {
    .....
  }
}


Ну или же ограничить использование вариадиков, например, стандартным std::tuple и расшивать его с помощью std::apply.