Open evilenzo opened 1 year ago
Варианты 2 и 3 кажутся нелогичными/неправильными, а 1 даже уже работает в GCC но с некоторыми ограничениями (https://gcc.godbolt.org/z/6xGTPo49h):
template <typename A, typename B>
struct TwoParams {};
void foo(TwoParams<auto, auto> arg);
void test() {
foo(TwoParams<int, int>());
foo(TwoParams<short, long>());
}
void bar(void(*)(auto)); // not ok
template<typename T>
using FPtr = void(*)(T);
void baz(FPtr<auto>); // ok
На примере bar
видно, что есть некоторые проблемы в том, чтобы заходя "вглубь" типа понимать, auto
это неявный шаблонный параметр внешней функции, или что-то другое.
Описание
На данный момент если мы хотим иметь какой-то констрейнт для шаблонного типа, мы пишем что-то в таком духе:
Это полезно и для пользователя, т.к. в объявлении он явно видит, что аргумент, например, обёрнут optional'ом, и для разработчика, т.к. он получает автокомплит от IDE. Но есть и несколько минусов, например, излишняя вербозность, в особенности, когда имя типа больше использоваться не будет. С 20-м стандартом появилась возможность переписать код подобным образом:
Но вербозность это не особо уменьшает и всё ещё имеет множество минусов, например, нужда реализовывать такие констрейнты под каждый тип. Чтобы решить проблему, предлагается такая запись:
Либо, как вариант, вообще самостоятельно не писать шаблонные параметры и разрешить такую запись:
Мотивация
Как было сказано выше, уменьшить вербозность, не писать лишний код, когда нам неинтересен сам тип, при этом иметь автокомплит и полезную информацию для пользователя.
Сложности
Нужно решить вопрос с несколькими параметрами у типа. Пример:
В случае с третьим вариантом есть вопросы по другим нюансам, например, когда таких аргументов несколько.
Полезные ссылки: