Я узнал, что lambdas в MSVC и GCC являются функторами, реализующими operator()
. В чем причина того, что они предпочитают функторам функционировать указатели?
Почему С++ лямбда реализована с помощью функтора вместо указателя на функцию?
Ответ 1
Проблема заключается в том, что функция лямбда в С++ может иметь дополнительное состояние (захваченные переменные aka context), которые должны быть переданы для каждого экземпляра (они могут отличаться для каждого экземпляра дескриптора одной и той же лямбда-функции).
Функция не может иметь состояние, связанное с дескриптором, с которым вы проходите. Если вы добавите такое состояние в указатель функции, вы в конце концов напишите обертку, которая должна быть вызвана, используя синтаксис скобки (operator()
), который, как оказалось, является функтором.
Примечательным фактом является то, что лямбда без захвата может быть преобразована в указатель функции. Это возможно только потому, что не требует такого дополнительного пространства.
Ответ 2
Функции не имеют состояния, поэтому они не смогут реализовать функциональность, требуемую lambdas.
Кроме того, вам гарантируется, что lambdas имеют уникальный тип, который вы действительно не можете делать только с функциями.
Ответ 3
В дополнение к уже упомянутой способности захвата производительность также является причиной. В общем случае указатель функции не может быть встроен. Функтором может быть. Вот почему std:: sort быстрее qsort. Как уже упоминалось, лямбда без захватов может быть превращена в указатель функции, но это в основном для взаимодействия со старыми c api. т.е. вы можете передать лямбду старой функции win32 api. В общем случае для простой лямбды компилятор предпочел бы встроить его.