You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Это полезно и для пользователя, т.к. в объявлении он явно видит, что аргумент, например, обёрнут optional'ом, и для разработчика, т.к. он получает автокомплит от IDE.
Но есть и несколько минусов, например, излишняя вербозность, в особенности, когда имя типа больше использоваться не будет.
С 20-м стандартом появилась возможность переписать код подобным образом:
template<typename T>
structis_optional : std::false_type {};
template <typename T>
structis_optional<std::optional<T>> : std::true_type {};
template <typename T>
concept Optional = is_optional<T>::value;
/* В некоторых случаях можно сделать так:template <typename T>concept Optional = std::is_same_v<std::optional<T::value_type>, T>;*/voidfoo(Optional auto opt_arg);
Но вербозность это не особо уменьшает и всё ещё имеет множество минусов, например, нужда реализовывать такие констрейнты под каждый тип.
Чтобы решить проблему, предлагается такая запись:
voidfoo(std::optional<auto> opt_arg);
Либо, как вариант, вообще самостоятельно не писать шаблонные параметры и разрешить такую запись:
voidfoo(std::optional opt_arg);
Мотивация
Как было сказано выше, уменьшить вербозность, не писать лишний код, когда нам неинтересен сам тип, при этом иметь автокомплит и полезную информацию для пользователя.
Сложности
Нужно решить вопрос с несколькими параметрами у типа. Пример:
template <typename A, typename B>
structTwoParams {};
// Вариант 1voidfoo(TwoParams<auto, auto> arg);
// Вариант 2voidfoo(TwoParams<auto> arg);
// Вариант 3voidfoo(TwoParams<auto...> arg);
В случае с третьим вариантом есть вопросы по другим нюансам, например, когда таких аргументов несколько.
Варианты 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-м стандартом появилась возможность переписать код подобным образом:
Но вербозность это не особо уменьшает и всё ещё имеет множество минусов, например, нужда реализовывать такие констрейнты под каждый тип.
Чтобы решить проблему, предлагается такая запись:
Либо, как вариант, вообще самостоятельно не писать шаблонные параметры и разрешить такую запись:
Мотивация
Как было сказано выше, уменьшить вербозность, не писать лишний код, когда нам неинтересен сам тип, при этом иметь автокомплит и полезную информацию для пользователя.
Сложности
Нужно решить вопрос с несколькими параметрами у типа. Пример:
В случае с третьим вариантом есть вопросы по другим нюансам, например, когда таких аргументов несколько.
Полезные ссылки:
The text was updated successfully, but these errors were encountered: