Разница между лямбдами C ++ 0x и operator (), замыканием и функтором - PullRequest
8 голосов
/ 11 января 2011

Я уверен, что получил общее представление о конструкциях, но не вижу цели их применения в c ++. Я читал предыдущие посты на эту тему здесь, в SO и в других местах, но не понимаю, почему они должны быть новой языковой функцией.

Вещи, на которые я бы хотел ответить, таким образом

  • В чем разница между лямбда и аргументом шаблона, принимающим функцию / функтор.

  • Является ли замыкание просто функтором с некоторым заданным состоянием объекта (область действия?)?

  • Что такое «приложение-убийца» для этих конструкций? или, может быть, типичный вариант использования?

Ответы [ 2 ]

17 голосов
/ 11 января 2011

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

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

11 голосов
/ 11 января 2011

Хорошо, вы на самом деле задаете кучу разных вопросов, возможно, потому что вы не совсем знакомы с терминологией. Я постараюсь ответить на все.

В чем разница между лямбда-выражением и оператором ()? - Давайте перефразируем это следующим образом: «В чем разница между лямбда-выражением и объектом с помощью operator ()?»

В принципе, ничего. Основное отличие состоит в том, что лямбда-выражение создает функциональный объект, в то время как объект с оператором () является функциональным объектом. Конечный результат достаточно похож, чтобы рассмотреть тот же объект, который может быть вызван с синтаксисом (params).

В чем разница между замыканием и функтором? Это также довольно запутано. Пожалуйста, просмотрите эту ссылку:

http://en.wikipedia.org/wiki/Closure_(computer_programming) http://en.wikipedia.org/wiki/Closure_(computer_programming)#C.2B.2B

Итак, как вы можете видеть, замыкание - это своего рода «функтор», который определяется внутри области видимости так, что он поглощает переменные, доступные ему в этой области видимости. Другими словами, это функция, которая создается на лету во время работы программы, и этот процесс построения параметризуется значениями времени выполнения содержащей ее области. Итак, в C ++ замыкания являются лямбдами, которые используют значения внутри функции, строящей лямбду.

В чем разница между лямбда и аргументом шаблона, принимающим функцию / функтор? - Это опять в замешательстве. Разница в том, что они на самом деле не похожи друг на друга. Шаблонный «аргумент», принимающий функцию / функтор, является уже запутанной формулировкой, поэтому я буду считать «аргументом» вы подразумеваете «функцию», потому что аргументы ничего не принимают. В этом случае, хотя лямбда-выражение может принимать функтор в качестве аргумента, он не может быть шаблонным. Во-вторых, обычно лямбда-это та, что передается в качестве аргумента функции, принимающей аргумент функтора.

Является ли замыкание просто функтором с некоторым заданным состоянием объекта (области действия?)?

Как видно по приведенной выше ссылке, нет. На самом деле закрытие даже не имеет состояния, на самом деле. Замыкание строится на основе состояния ON некоторого другого объекта, который его построил, внутри этого функтора, хотя это не состояние, а сама конструкция объекта.

Что такое «приложение-убийца» для этих конструкций? или, может быть, типичный вариант использования?

Я перефразирую это: "Почему эти вещи полезны?"

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

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

...