У нас была функция, которая использовала не захватывающую внутреннюю лямбду, например:
void foo() {
auto bar = [](int a, int b){ return a + b; }
// code using bar(x,y) a bunch of times
}
Теперь функциональность, реализованная лямбда-выражением, стала необходимой в другом месте, поэтому я собираюсь вывести лямбда-вывод из foo()
области глобальных пространств имен. Я могу либо оставить его как лямбду, сделав опцию копирования-вставки, либо изменить его на правильную функцию:
auto bar = [](int a, int b){ return a + b; } // option 1
int bar(int a, int b){ return a + b; } // option 2
void foo() {
// code using bar(x,y) a bunch of times
}
Изменение его на правильную функцию тривиально, но это заставило меня задуматься, есть ли какая-то причина не оставлять это как лямбду? Есть ли причина не использовать везде лямбды вместо «обычных» глобальных функций?
Ответы:
Есть одна очень важная причина не использовать глобальные лямбды: потому что это не нормально.
Синтаксис регулярных функций C ++ существует со времен C. Программисты десятилетиями знали, что означает этот синтаксис и как они работают (хотя по общему признанию тот факт, что распад функции указателя иногда кусает даже опытных программистов). Если программист C ++ любого уровня квалификации, кроме «абсолютного новичка», видит определение функции, он знает, что получает.
Глобальная лямбда - это совсем другой зверь. Это поведение отличается от обычной функции. Лямбды - это объекты, а функции - нет. У них есть тип, но этот тип отличается от типа их функции. И так далее.
Итак, теперь вы подняли планку в общении с другими программистами. Программист C ++ должен понимать лямбды, если они хотят понять, что делает эта функция. И да, это 2019 год, так что приличный программист на С ++ должен иметь представление о том, как выглядит лямбда. Но это все еще более высокая планка.
И даже если они это поймут, вопрос у программиста будет такой: почему автор этого кода написал это так? И если у вас нет хорошего ответа на этот вопрос (например, потому что вы явно хотите запретить перегрузку, как в точках настройки Ranges), то вам следует использовать общий механизм.
Предпочитайте ожидаемые решения новым, где это уместно. Используйте наименее сложный способ донести свою точку зрения.
источник
Я могу подумать о нескольких причинах, по которым вы хотели бы избегать глобальных лямбд в качестве замены для обычных функций:
«Почему я не должен использовать лямбда-выражения для замены функторов с состоянием (классов)?»
источник
std::integral_constant
для этого ...Спросив, я подумал о причине, по которой не следует этого делать: поскольку это переменные, они подвержены статическому порядку инициализации Fiasco ( https://isocpp.org/wiki/faq/ctors#static-init-order ), который может вызвать ошибки по линии.
источник
constexpr
лямбдами ... Суть в том, чтобы просто использовать функцию.Задача определенного уровня сложности требует решения, по крайней мере, такой же сложности. Но если есть и менее сложное решение для той же проблемы, тогда нет никаких оснований для использования более сложного. Зачем вводить сложность, которая вам не нужна?
Между лямбдой и функцией функция является просто менее сложным видом сущности из двух. Вы не должны оправдывать не использование лямбды. Вы должны оправдать использование одного. Лямбда-выражение вводит тип замыкания, который является безымянным типом класса со всеми обычными специальными функциями-членами, оператором вызова функции и, в этом случае, неявным оператором преобразования в указатель на функцию, и создает объект этого типа. Инициализация копирования глобальной переменной из лямбда-выражения просто делает намного больше, чем просто определение функции. Он определяет тип класса с шестью неявно объявленными функциями, определяет еще две операторные функции и создает объект. Компилятор должен сделать намного больше. Если вам не нужны какие-либо функции лямбды, не используйте лямбду…
источник
Лямбды - это анонимные функции .
Если вы используете именованную лямбду, это означает, что вы в основном используете именованную анонимную функцию. Чтобы избежать этого оксюморон, вы можете также использовать функцию.
источник
Мы привыкли использовать функции вместо глобального функтора, поэтому он нарушает согласованность и принцип наименьшего удивления .
Основными отличиями являются:
источник