Подтвердить что ты не робот

С++ 0x лямбда против блоков

Я изучал С++ 0x сегодня, и я столкнулся с новой функцией лямбда. Мой вопрос в том, как эти разные (с точки зрения использования) из блоки и почему они могут предпочесть друг другу?

Спасибо.

4b9b3361

Ответ 1

существует короткий синтаксис с С++ 0x lambdas, чтобы взять каждую переменную в объем по ссылке. ([&]) Тип лямбда также не указан, позволяя потенциально более оптимальный код.

Теперь, когда вы смотрите на блоки Apple, для этого потребуются спецификаторы __block добавляется к переменным, которые вы хотите изменить (тот факт, что это требует, чтобы вся система была дефектной). Переменные принимаются по ссылке, но затем по значению, когда блок выходит из области действия (и Скопированный контекст обязательно живет на куче, кажется). Странно семантика, которая приведет только к нарушенным проектам, но, вероятно, делает люди, которые любят GC счастливы. Не сказав, что это, вероятно, конечно, потому что для этого требуются специальные направления.

Утверждается, что синтаксис Lambdas С++ 0x нарушит совместимость с C, но я не думаю, что это правда. Возможно, есть и другие проблемы интегрировать его с C, хотя, в основном, тот факт, что C не может действительно имеют дело с неуказанными типами и стиранием типа типа.

Блоки Apple - это просто функция ObjC, которую они пытаются обобщить. Другие языки. Для С++ система, разработанная для этого языка, просто намного лучше.

EDIT:

Чтобы должным образом дать кредит, я долгое время принимал эту информацию от http://www.rhinocerus.net/forum/language-c-moderated/558214-blocks-vs-c-lambdas.html. Теперь эта связь мертва; однако исходное обсуждение, похоже, архивировано здесь, благодаря @stefan для его поиска.

Ответ 2

Я думаю, это в основном сводится к вопросу о вашей отправной точке. Если вы начинаете с Objective-C и записываете С++ (Objective-C ++) в основном (или исключительно) в качестве дополнения к Objective-C, то использование блоков по всему коду может иметь смысл, просто сохранить как можно больше общности насколько это возможно, через базу кода. Даже если (например) в проекте использовались некоторые фрагменты, написанные в Objective-C, а другие в С++, было бы целесообразно использовать блоки как в том, чтобы сохранить как можно больше подобия по всей кодовой базе.

Однако, если вы используете их вне С++, я не вижу причин предпочитать блоки с помощью lambdas на С++. В том, что я предполагаю, что это наиболее распространенное использование (предикат или действие в алгоритме), единственное заметное различие между ними состоит в том, что один начинается с ^, а другой с [].

Старые версии Objective С++

До ARC были внутренние различия в реализации блоков и лямбда, которые могли повлиять на некоторые более сложные применения. Например, блоки работали смутно, как строки C, поэтому вы использовали Block_copy для копирования одного, Block_release, чтобы освободить копию и так далее. С другой стороны, в С++ все это автоматизировано, поэтому копия ctor автоматически использует Block_copy и dtor Block_release по мере необходимости. В то же время, это было связано с немного более "волшебным", поэтому (например), когда вы копируете блок, копия всегда распределяется динамически, независимо от того, как был выделен источник.

Если по той или иной причине вы застряли в использовании более старого (я пытаюсь сказать "древний" ) компилятор или поддерживая старый код (и не хочу обновлять кодовую базу в целом), разница в управлении памятью может быть целесообразной.

Ответ 3

Майк Эш предоставляет подробное сравнение . Блоки и лямбды отличаются по своему синтаксису, типу данных, способу захвата переменных, способу их работы при копировании и их производительности.

Как они относятся к C/С++/ Objective-C:

Я буду ссылаться на расширение блоков Apple, поскольку "Objective-C блокирует" даже хотя это не совсем правильно. Они на самом деле являются дополнением к C (и может даже использоваться на С++), с некоторыми дополнительными поведением, чтобы сделать они более полезны в Objective-C. Однако они глубоко переплетаются с Objective-C в их реализации, а "C-блоки" являются неопределенными, поэтому Я думаю, что "Objective-C blocks" - лучший способ ссылаться на них здесь.

С++ 0x lambdas являются частью только С++ и не могут использоваться из C. Предположительно, они могут использоваться в Objective-C ++, если компилятор поддерживает С++ 0x.

Очень высокоуровневое резюме различий:

Блоки

Objective-C несколько проще писать и использовать, особенно в случае их использования для асинхронного или фонового задачи, в которых блок должен быть скопирован и сохранен в срок действия области, в которой он был создан. С++ 0x lambdas в конечном счете обеспечивают большую гибкость и потенциальную скорость, но значительная сложность.

Ответ 4

По последним версиям clang (3.2, 3.3rc и 3.4svn) они взаимозаменяемы в коде Objective-C (++). В С++ вы должны использовать lambda, но в Objective-C (++), если у вас

  • Поддержка С++ в вашем libobjc.

    У Apple libobjc.B.dylib есть это наверняка. Если вы используете GNUstep, вам нужно либо скомпилировать libobjc2 (и только libobjc2) с cmake, либо связать с libsupС++ (или любую другую библиотеку С++ ABI) или связать свой проект с libobjcxx, а также
  • Блокировки должны существовать.

    Это часть libSystem.dylib для OS X, с которой связан libc, поэтому это не проблема. Вы можете использовать LLVM compiler-rt для этого или использовать libobjc2. Я лично рекомендую вам использовать libobjc2, поскольку он предоставляет среду исполнения Blocks, которая совместима с остальной частью GNUstep, которая также требуется.
  • Основание.

    Это связано с тем, как clang обрабатывает ABI для взаимозаменяемости блоков С++ lambda и Objective-C. clang делает это с NSAutoreleasePool, который является частью Foundation.

тогда вы можете безопасно обменивать детали.