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

Сообщение Re[13]: Carbon от 09.04.2024 21:29

Изменено 09.04.2024 21:34 vdimas

Re[13]: Carbon
Здравствуйте, so5team, Вы писали:

S>
S>template<std::integral T>
S>void f1(T /*v*/) {}

S>void f2(std::integral auto /*v*/) {}

S>template<typename T>
S>void f3(T /*v*/) requires std::integral<T> {}
S>


S>Попробуйте объяснить какой из этих вариантов наиболее удобен и почему.


Для простейших случаев второй, вестимо.

Для нескольких requires подходит только последний.

Насчёт того, что с синтаксисом что-то надо делать — согласен.
Второй вариант уже что-то делает с синтаксисом, но он работает только для аргументов-типов, а хотелось бы еще с константами времени компиляции.

Например что-то типа такого:
void fn<int c>(auto arg1, auto arg2) {}

Эквивалент
template<int c, typename T1, typename T2>
void fn(T1 arg1, T2 arg2) {}


Более сложный вариант:
void fn<int c, typename T3<int, typename T4>>(auto arg1, auto arg2) {}

Или даже сделать typename опциональным-дефолтным, тогда:
void fn<int c, T3<int, T4> >(auto arg1, auto arg2) {}

(хотя, здесь такие же опасения, как для var/let — требуется ли явное указание, что вводится новая сущность, чтобы избежать ошибок переприсвоения уже имеющейся переменной, в данном случае — переменной типа, которая внезапно может оказаться уже определённым символом в данном контексте, таким же int, например)
Эквивалент
template<int c, template<int, typename T4> typename T3, typename T1, typename T2>
void fn(T1 arg1, T2 arg2) {}


При наличи конструкций ->decltype() предварительный синтаксис template<> уже не столь нужен, т.к. есть альтернативный способ вывода типа результата шаблонных ф-ий.
Re[13]: Carbon
Здравствуйте, so5team, Вы писали:

S>
S>template<std::integral T>
S>void f1(T /*v*/) {}

S>void f2(std::integral auto /*v*/) {}

S>template<typename T>
S>void f3(T /*v*/) requires std::integral<T> {}
S>


S>Попробуйте объяснить какой из этих вариантов наиболее удобен и почему.


Для простейших случаев второй, вестимо.

Для нескольких requires подходит только последний.

Насчёт того, что с синтаксисом что-то надо делать — согласен.
Второй вариант уже что-то делает с синтаксисом, но он работает только для аргументов-типов, а хотелось бы еще с константами времени компиляции.

Например что-то типа такого:
void fn<int c>(auto arg1, auto arg2) {}

Эквивалент
template<int c, typename T1, typename T2>
void fn(T1 arg1, T2 arg2) {}


Более сложный вариант:
void fn<int c, typename T3<int, typename T4>>(auto arg1, auto arg2) {}

Или даже сделать typename опциональным-дефолтным, тогда:
void fn<int c, T3<int, T4> >(auto arg1, auto arg2) {}

(хотя, здесь такие же опасения, как для var/let — требуется ли явное указание, что вводится новая сущность, чтобы избежать ошибок переприсвоения уже имеющейся переменной, в данном случае — переменной типа, которая внезапно может оказаться уже определённым символом в данном контексте, таким же int, например)

Эквивалент
template<int c, template<int, typename T4> typename T3, typename T1, typename T2>
void fn(T1 arg1, T2 arg2) {}

При наличи конструкций ->decltype() предварительный синтаксис template<> уже не столь нужен, т.к. есть альтернативный способ вывода типа результата шаблонных ф-ий.