Добавление лямбда-функций и замыканий дает языку C++ какие-то принципиально новые возможности? Или все что можно сделать используя лямбда-функции и замыкания можно было делать и раньше другими средствами языка?
Например, деструкторы в C++ нельзя заменить никакими средствами языка C.
Здравствуйте, Максим Рогожин, Вы писали:
МР>Добавление лямбда-функций и замыканий дает языку C++ какие-то принципиально новые возможности? Или все что можно сделать используя лямбда-функции и замыкания можно было делать и раньше другими средствами языка?
Просто избавляют от необходимости определять самому новые функции и классы. Ведь фактически любая лямбда — это просто объект автоматически сгенерированного класса с определенным operator(). Если лямбда использует auto в списке формальных параметров, operator() будет шаблонной функцией-членом. Вот и вся магия. Можно обойтись без лямд, ценой ухудшения компактности кода и засорения пространств имен лишними именами.
--
Справедливость выше закона. А человечность выше справедливости.
Re: Дают ли lambdas какие-то принципиально новые возможности?
Здравствуйте, Максим Рогожин, Вы писали:
МР>Например, деструкторы в C++ нельзя заменить никакими средствами языка C.
Яб поспорил. Можно, если перегрузить {}, и все объекты объявлять специальным макросом, который добавляет объект в специальный список, а } будет чистить этот список.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[2]: Дают ли lambdas какие-то принципиально новые возможности?
Здравствуйте, rg45, Вы писали:
R>Можно обойтись без лямд, ... и засорения пространств имен лишними именами.
Шарповый компилятор авто-именует лямбда-функции. В плюсах такого нет?
Re[3]: Дают ли lambdas какие-то принципиально новые возможности?
Здравствуйте, Mihas, Вы писали:
R>>Можно обойтись без лямд, ... и засорения пространств имен лишними именами. M>Шарповый компилятор авто-именует лямбда-функции. В плюсах такого нет?
Разумеется, C++ компилятор так же обеспечивает уникальность имен всех автоматически генерируемых сущностей. Но мы же говорим о том, что будет, если отказаться от лямбд. Или я не понял вопрос?
--
Справедливость выше закона. А человечность выше справедливости.
Re[4]: Дают ли lambdas какие-то принципиально новые возможности?
Здравствуйте, rg45, Вы писали:
R>>>Можно обойтись без лямд, ... и засорения пространств имен лишними именами. M>>Шарповый компилятор авто-именует лямбда-функции. В плюсах такого нет? R>Разумеется, C++ компилятор так же обеспечивает уникальность имен всех автоматически генерируемых сущностей. Но мы же говорим о том, что будет, если отказаться от лямбд. Или я не понял вопрос?
Все верно.
Мой вопрос — не аргумент за или против лямбда-функций, а прояснение для себя. Не засоряется пространство имен в мозгу разработчика.
Re: Дают ли lambdas какие-то принципиально новые возможности?
Здравствуйте, Максим Рогожин, Вы писали:
МР>Добавление лямбда-функций и замыканий дает языку C++ какие-то принципиально новые возможности? Или все что можно сделать используя лямбда-функции и замыкания можно было делать и раньше другими средствами языка?
Поддержка лямбда выражений дала возможность локализации кода в месте обработки или вычисления.
Re: Дают ли lambdas какие-то принципиально новые возможности
Здравствуйте, Максим Рогожин, Вы писали:
МР>Добавление лямбда-функций и замыканий дает языку C++ какие-то принципиально новые возможности? Или все что можно сделать используя лямбда-функции и замыкания можно было делать и раньше другими средствами языка?
Нет, в бусте сделали их имитацию средствами С++03:
Здравствуйте, Максим Рогожин, Вы писали:
МР>Добавление лямбда-функций и замыканий дает языку C++ какие-то принципиально новые возможности? Или все что можно сделать используя лямбда-функции и замыкания можно было делать и раньше другими средствами языка?
Появилась возможность создавать локальные функции. Без засорения внешнего пространства имен. Например:
Здесь need_erase -- это классическая локальная функция, которая имеет доступ к контексту, внутри которого она определена. Другими средствами этого же можно было бы добиться либо определением какой-то дополнительной сущности, хранящей в себе часть контекста. Либо же посредством макросов. Но дополнительная сущность -- это лишняя работа. А макросы -- это зло
Re[2]: Дают ли lambdas какие-то принципиально новые возможности?
Здравствуйте, so5team, Вы писали:
S>Появилась возможность создавать локальные функции. Без засорения внешнего пространства имен.
тут согласен
S>Например:
...... S>А макросы -- это зло
ну твоя локальная функция — тоже зло, ибо неявно хватает тот самый контекст
код был бы понятнее, имхо, если бы ты передал хотя бы it в эту функция явно
ну и глубину скоупов можно уменьшить:
void storage_t::drop_subscription_for_all_states(
const mbox_t & mbox_ref,
const std::type_index & type_index )
{
const key_t key( mbox_ref->id(), type_index );
auto need_erase = [&] ( auto i ) {
return i != m_map.end() && key.is_same_mbox_msg_pair( i->first );
};
auto it = m_map.lower_bound( key );
if( !need_erase( it ) )
return;
do
{
m_hash_table.erase( &(it->first) );
m_map.erase( it++ );
}
while( need_erase( it ) );
mbox_ref->unsubscribe_event_handlers( type_index, owner() );
}
ps. маньячные пробелы для аргументов
Re[3]: Дают ли lambdas какие-то принципиально новые возможности?
Здравствуйте, uzhas, Вы писали:
S>>Появилась возможность создавать локальные функции. Без засорения внешнего пространства имен. U>тут согласен
Ну надо же, как нам повезло!
U>ну твоя локальная функция — тоже зло, ибо неявно хватает тот самый контекст U>код был бы понятнее, имхо, если бы ты передал хотя бы it в эту функция явно U>ну и глубину скоупов можно уменьшить:
Своим преждевременным return-ом и передачей аргумента в локальную функцию вы усложнили код, наши поздравления.
Re: Дают ли lambdas какие-то принципиально новые возможности?
Здравствуйте, Максим Рогожин, Вы писали:
МР>Привет, всем!
МР>Добавление лямбда-функций и замыканий дает языку C++ какие-то принципиально новые возможности?
Нет. Принципиально новые возможности это SIMD и #pragma omp и тому подобное.
МР>Или все что можно сделать используя лямбда-функции и замыкания можно было делать и раньше другими средствами языка?
Язык полный по тюрингу позволяет реализовать всё, что душе угодно.
МР>Например, деструкторы в C++ нельзя заменить никакими средствами языка C.
Как нельзя? Кто запрещает вызывать функции очистки руками.
Re: Дают ли lambdas какие-то принципиально новые возможности?
Здравствуйте, Максим Рогожин, Вы писали:
МР>Добавление лямбда-функций и замыканий дает языку C++ какие-то принципиально новые возможности?
Разумеется, нет. Любая программа пишется с помощью циклов, условий и вызовов. подпрограмм.
PS.
Я тут две недели пописал на С (без плюсов). Это утомительно.
Но если вспомнить приёмы программирования, которые сам же употреблял двадцать лет назад...
Даже и кода оказывается ненамного больше.
Течёт вода Кубань-реки куда велят большевики.
Re[4]: Дают ли lambdas какие-то принципиально новые возможности?
Здравствуйте, so5team, Вы писали:
S>Своим преждевременным return-ом
так в плюсах принято. как только понял, что делать нечего — выходи. в сях по-другому (но мы же претендуем на плюсовый код? ), ибо нет RAII
можно почитать хотя бы тут: https://stackoverflow.com/questions/36707/should-a-function-have-only-one-return-statement
в swift даже есть клевый guard для этих целей
S>передачей аргумента в локальную функцию вы усложнили код
усложнение — это когда функция без аргументов возвращает то true, то false =)
Re[5]: Дают ли lambdas какие-то принципиально новые возможности?
Здравствуйте, uzhas, Вы писали:
U>так в плюсах принято. как только понял, что делать нечего — выходи.
Ну вот в своем коде вы можете делать все, что захотите. Хоть преждевременный return, который легко не заметить, хоть передачу аргументов, хотя это вполовину уменьшает ценность локальной функции. Что угодно.
Re[4]: Дают ли lambdas какие-то принципиально новые возможности?
Здравствуйте, Максим Рогожин, Вы писали:
МР>Привет, всем!
МР>Добавление лямбда-функций и замыканий дает языку C++ какие-то принципиально новые возможности? Или все что можно сделать используя лямбда-функции и замыкания можно было делать и раньше другими средствами языка?
МР>Например, деструкторы в C++ нельзя заменить никакими средствами языка C.
Лямбды позволяют активно использовать в коде функции высшего порядка, т.е. функции, принимающие функции в качестве аргументов.
Здравствуйте, scf, Вы писали:
scf>std::for_each(v.begin(), v.end(),
scf>Если бы STL не был приветом из 90х, этот код выглядел бы вот так:
scf>v.for_each([](auto i)
Весь смысл STL в разделении данных и алгоритмов, для того чтобы работали многие алгоритмы требуются итераторы произвольного доступа. Я не уверен хорошо это или плохо, с одной стороны код многословней, с другой иначе пришлось бы дублировать алгоритмы в контейнерах.
Re[5]: Дают ли lambdas какие-то принципиально новые возможности?
Здравствуйте, uzhas, Вы писали:
U>так в плюсах принято. как только понял, что делать нечего — выходи. в сях по-другому (но мы же претендуем на плюсовый код? ), ибо нет RAII U>можно почитать хотя бы тут: https://stackoverflow.com/questions/36707/should-a-function-have-only-one-return-statement U>в swift даже есть клевый guard для этих целей U>усложнение — это когда функция без аргументов возвращает то true, то false =)
Похоже, что некоторые не понимают очевидных вещей, поэтому поясним развернуто.
1. Очевидно, существует, как минимум три способа записать и использовать локальную функцию need_erase:
первый:
auto need_erase = [&](const auto & k, const auto & i) {...};
if(need_erase(key, it))...
второй:
auto need_erase = [&](const auto & i) {...};
if(need_erase(it))...
третий:
auto need_erase = [&]{...};
if(need_erase())...
Второй способ, т.е. предпочитаемый вами, в данном случае выглядит наименее логичным и выгодным, потому что:
не понятно, почему в лямбде захватывается key, а итератор передается параметром. key -- это такой же локальный объект, как и it. Тогда как первый и третий варианты таких вопросов не вызывают вообще, там либо все параметрами, либо ничего;
не дает существенного выигрыша в лаконичности использования need_erase.
2. need_erase не нуждается в аргументах, поскольку ее можно рассматривать как аналог булевой переменной вот в таком варианте записи кода:
Т.е. need_erase -- это показатель текущего статуса хода выполнения алгоритма. На каждом шаге этот статус обновляется и проверяется. Лямбды в виде локальных функций позволяют записать это максимально лаконично, но при этом не потеряв в понятности кода. Для чего именно этот пример и был приведен.
Еще по поводу функций без параметров, возвращающих то true, то false: попробуйте применить этот же аргумент к std::vector::empty(), например.
3. В C++ не обязательно придерживаться принципа "единственный return" на всю функцию, в отличии от C и других процедурных языков. Но это не значит что в C++ return из середины функции нужно делать всегда. Правило единственнго return-а появилось очень давно (возможно, еще до появления C++) и относилось оно не столько к проблеме очистки ресурсов, сколько к понятности кода функции. В данном случае нам было принципиально важно, чтобы в коде было четко видно, что цикл с последующим unsubscribe_event_handlers должен выполняться только, если вообще было найдено что-то для удаление. Запись этих действий в блоке под if-ом показывает это намного более явно, чем преждевременный return в середине функции.
4. Очевидно, что оригинальный код не вызвал у вас никаких проблем с его пониманием. Следовательно, код успешно справляется с поставленными целями: и работу свою выполняет, и понятен окружающим. Ваш вариант решения с точки зрения понятности может вызывать дополнительные вопросы. В частности, к тому самому преждевременному return-у, который теперь приходится учитывать при чтении второй половины кода функции.
Собственно к чему это все было рассказано: принятые решения имеют свои обоснования, код был написан так, как он был написан не потому, что так получилось или просто так захотелось. Вас эти аргументы могут не убедить. Равно как и нас ваши аргументы. Следовательно, здесь спор будет идти об эстетических пристрастиях. А это, во-первых, бессмыслено. И, во-вторых, никак не относится к первоначальному посылу о том, что лямбды в C++11 сделали возможным написание локальных функций, имеющих полный доступ к локальному контексту.
Re[4]: Дают ли lambdas какие-то принципиально новые возможности?