Почему С++ лямбда реализована с помощью функтора вместо указателя на функцию?

Я узнал, что lambdas в MSVC и GCC являются функторами, реализующими operator(). В чем причина того, что они предпочитают функторам функционировать указатели?

Ответ 1

Проблема заключается в том, что функция лямбда в С++ может иметь дополнительное состояние (захваченные переменные aka context), которые должны быть переданы для каждого экземпляра (они могут отличаться для каждого экземпляра дескриптора одной и той же лямбда-функции).

Функция не может иметь состояние, связанное с дескриптором, с которым вы проходите. Если вы добавите такое состояние в указатель функции, вы в конце концов напишите обертку, которая должна быть вызвана, используя синтаксис скобки (operator()), который, как оказалось, является функтором.

Примечательным фактом является то, что лямбда без захвата может быть преобразована в указатель функции. Это возможно только потому, что не требует такого дополнительного пространства.

Ответ 2

Функции не имеют состояния, поэтому они не смогут реализовать функциональность, требуемую lambdas.

Кроме того, вам гарантируется, что lambdas имеют уникальный тип, который вы действительно не можете делать только с функциями.

Ответ 3

В дополнение к уже упомянутой способности захвата производительность также является причиной. В общем случае указатель функции не может быть встроен. Функтором может быть. Вот почему std:: sort быстрее qsort. Как уже упоминалось, лямбда без захватов может быть превращена в указатель функции, но это в основном для взаимодействия со старыми c api. т.е. вы можете передать лямбду старой функции win32 api. В общем случае для простой лямбды компилятор предпочел бы встроить его.