Почему лямбда-выражения шаблонов С++ 20 используют ключевое слово typename?

Я понимаю аргумент согласованности, но большинство параметров для шаблонов являются типами, поэтому я чувствую, что, поскольку лямбда-выражения предназначены для краткого определения структуры, по умолчанию, вероятно, следует использовать typename/class (вам все равно нужно будет написать int/size_t/short) .

Если кто-то не знаком с изменениями лямбда-выражений в C++20, вот пример:

[]<typename T>(const std::vector<T>& v)
{
    for(const auto& x : v) { std::cout << x; }
};

и мой вопрос почему бы и нет:

[]<T>(const std::vector<T>& v)
{
    for(const auto& x : v) { std::cout << x; }
};
[](const std::vector<auto> &v) { }; работает в GCC9, хотя я не уверен, что это стандарт. Я думаю, что концепции TS допускают такой синтаксис.
metalfox 07.06.2019 12:25
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
766
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Если вы просто напишите

[]<T>(){ }

что такое T?

А typename? Значение auto?

Мне кажется, что в лямбдах, как и в обычных функциях, необходимо явно указывать, что такое аргумент шаблона.

И если вы можете сделать вывод, что T является типом из использования (если он используется в качестве первого аргумента шаблона для std::vector, он должен быть типом), зачем упрощать только синтаксис лямбда, а не также синтаксис традиционных функций шаблона?

Хотя краткость действительно является преимуществом лямбда-выражений, она не настолько важна, чтобы заменить необходимость согласованности. Это особенно верно для функций, использующих шаблоны, поскольку их труднее понять, чем функции языка без шаблонов.

В частности, синтаксис шаблона для универсальных лямбда-выражений имеет узкую область применения, т. е. большинство лямбда-выражений могут обходиться без него (на самом деле приведенный вами пример — прекрасный пример того, как его не использовать, поскольку тело функции не создает экземпляр T или делает что-то подобное). Из P0428 (выделено мной):

There are a few key reasons why the current syntax for defining generic lambdas is deemed insufficientby the author. The gist of it is that some things that can be done easily with normal functiontemplates require significant hoop jumping to be done with generic lambdas, or can’t be done at all.

Общие лямбды с использованием decltype в их теле, вероятно, будут наиболее заметными клиентами новых функций. А замена decltype/decay_t-хитрости на <typename T> мне кажется более приемлемой с точки зрения дополнительной типизации и лаконичности.

Ответ принят как подходящий

Проблема в том, что этот уже имеет значение:

template <T> void foo();

Это шаблон функции с одним параметром шаблона, который является параметром шаблона не тип с типом T, и этот параметр шаблона не имеет имени.

Было бы довольно запутанно, если бы один и тот же синтаксис означал очень разные вещи в зависимости от того, вводите ли вы шаблон функции или общую лямбду, то есть два очень похожих контекста, служащих одинаковым целям!

Кроме того... что бы вы сделали, если бы вам действительно нужен параметр шаблона, не являющийся типом? Просто не может иметь один?

Можете ли вы привести полный пример: уже имеет значение? Я не понимаю этого. Я пробовал это, но clang/gcc не согласен, если это действительно cpp godbolt.org/z/hghhjc

NoSenseEtAl 10.06.2019 12:42

@NoSenseEtAl Вам нужен auto operator <=>(T const &) = default; в вашей структуре, чтобы это работало, что до сих пор не поддерживается этими компиляторами.

metalfox 10.06.2019 15:00

@NoSenseEtAl Этот будет действительной программой C++20, просто еще не реализованной. Этот — допустимая программа C++11.

Barry 10.06.2019 15:04

ах, хорошо, если у вас есть время, поместите это в A, так как мне не ясно, что вы говорили об использовании «псевдонима»

NoSenseEtAl 10.06.2019 23:19

@NoSenseEtAl Я не говорил об использовании псевдонимов. Я говорил об использовании имени типа Любые. Пример мог быть просто template <int> void foo();, работает отлично.

Barry 10.06.2019 23:39

Хорошо, но это не совсем реалистично... но в любом случае я получаю ваш ответ: иногда <bla> означает тип с именем bla, и если это означает "переменную" с именем bla, это может сбить с толку...

NoSenseEtAl 11.06.2019 17:39

@NoSenseEtAl Что не совсем реалистично? Иметь нетиповые параметры шаблона типа int или вообще иметь нетиповые параметры шаблона?

Barry 11.06.2019 17:45

Прошу прощения за плохую формулировку... Я имел в виду, что нереально ожидать, что люди будут использовать int в качестве нового имени типа (в моей версии лямбда без имени типа), но я предполагаю, что некоторые типы, такие как Time, Size или Robot, могут побольше путаницы...

NoSenseEtAl 11.06.2019 17:50

tl; dr Теперь я понимаю ваш аргумент, но я не получил его из ответа ... (это сбивало с толку, что T не определен как тип в A)

NoSenseEtAl 11.06.2019 17:50

Другие вопросы по теме