Какая польза от создания анонимной функции и ее немедленного вызова?

Я читаю такой код на С++:

const auto candidate_path = std::invoke([&]() {
  if (status == ModuleStatus::SUCCESS || status == ModuleStatus::FAILURE) {
    // clear candidate path if the module is finished
    return convertToPath(nullptr, false, planner_data);
  }
  return convertToPath(
    observer.lock()->getPathCandidate(), observer.lock()->isExecutionReady(), planner_data);
});

Код создает анонимную функцию и захватывает все по ссылке [&](){}, а затем вызывает ее std::invoke(). Я хотел бы посмотреть, есть ли от этого какая-нибудь польза?

Спасибо.

Это похоже на вопрос типа списка. Вопрос в виде списка не по теме/не по теме?

user12002570 29.07.2024 08:00
candidate_path может быть константой
Raffallo 29.07.2024 08:01

Он действительно создает область видимости, которая связана с внешним миром одним оператором возврата. В основном это делается для управления исходной мутацией и вспомогательными материалами для возвращаемого объекта. Иногда его используют для обхода недостатков конструкторов.

alfC 29.07.2024 08:06
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
4
89
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Переменная candidate_path должна быть const-квалифицированной. Немедленно вызываемая лямбда позволяет использовать (несколько) операторов для инициализации переменной, а не просто одно выражение после =, не жертвуя const.

В этом конкретном случае это сработало бы и с использованием тернарного оператора в одном выражении, но это может быть сложнее читать.

Причина использования std::invoke для вызова лямбды вместо записи [&](){ /*...*/ }(), вероятно, связана с личными предпочтениями автора. Возможная причина, которую я вижу, заключается в том, что легче распознать вызов лямбды. При использовании синтаксиса прямого вызова функции можно легко пропустить () в конце.

Предназначена ли функция lamda/std::invoke для инициализации const? Я должен сказать, что C++ сложен, некоторые побочные эффекты используются как обычная практика (или даже общие шаблоны).

Felix F Xu 29.07.2024 08:38

@FelixFXu Нет, лямбды в гораздо большей степени полезны как более простая альтернатива определяемым пользователем классам в качестве функциональных объектов, когда вы хотите передать «функцию» с состоянием другой функции. Фактическая цель std::invoke — унифицировать различный синтаксис «вызова» для разных типов объектов, например, чтобы иметь возможность обрабатывать указатели на функции-члены, которые в противном случае нужно было бы вызывать как obj.*mptr() так же, как вызов функции, принимающий объект в качестве дополнительного первого аргумента. : std::invoke(mptr, obj);. Это полезно при общем программировании с использованием шаблонов.

user17732522 29.07.2024 09:57

@FelixFXu Я не знаю, что вы имеете в виду под побочными эффектами, но используемый здесь шаблон имеет целью уменьшить возможные побочные эффекты, гарантируя наличие только const переменных. По сути, это что-то вроде импровизированного стиля функционального программирования.

user17732522 29.07.2024 09:59

@FelixFXu Лямбды в целом важны, и каждый, кто пишет на C++, должен их знать. Немедленно вызываемый лямбда-шаблон не так уж важен и поначалу может показаться запутанным, но станет естественным и очевидным, как только вы увидите/используете его несколько раз. std::invoke — это не то, что обычно нужно знать пользователям C++. Это актуально только для авторов библиотек, которым необходимо, чтобы функциональность их библиотеки была как можно более универсальной. Для используемого здесь шаблона он не нужен, и я не часто вижу, чтобы он использовался таким образом.

user17732522 29.07.2024 10:03

@FelixFXu Кроме того, если вы еще новичок в C++, код, который вы показываете, явно написан кем-то со значительным опытом. Он также использует другие неочевидные шаблоны, например, способ использования блокировки. К сожалению, C++ слишком сложен, чтобы можно было понять код, написанный опытным пользователем, использующим множество его функций, имея лишь базовое понимание языка. Учиться нужно маленькими шагами.

user17732522 29.07.2024 10:12

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