Лямбды в C++. Как это работает

Рассмотрим такой пример кода:

void f(int i) {     auto g = [i](auto j)     {         return i + j;     };     g = [i](auto j)     {         return i - j;     };     g(1); } 

При компиляции возникнет ошибка в строке g = [i](auto j).

Почему так происходит?

Дело в том, что лямбды в C++ — это всего-лишь синтаксический сахар над локальными классами/структурами с определённым [возможно шаблонным] оператором «скобки»:

class Lambda1 {     int i;  public:     Lambda1(int i) : i(i) {}      template <class Ty> auto operator()(Ty j)     {         return i + j;     } };  class Lambda2 {     int i;  public:     Lambda2(int i) : i(i) {}      template <class Ty> auto operator()(Ty j)     {         return i - j;     } };  void f(int i) {     auto g = Lambda1(i);     g = Lambda2(i);     g(1); } 

Теперь причина ошибки [в строке g = Lambda2(i);] становится очевидной: Lambda1 и Lambda2 — это различные классы, которые ничего не знают друг о друге.

Данные классы пришлось сделать глобальными, т.к. C++ всё ещё не поддерживает шаблонные методы в локальных классах.

В будущих версиях C++ вполне валидно будет писать так:

void f(int i) {     class Lambda1     {         int i;      public:         Lambda1(int i) : i(i) {}          template <class Ty> auto operator()(Ty j)         {             return i + j;         }     };     auto g = Lambda1(i);     class Lambda2     {         int i;      public:         Lambda2(int i) : i(i) {}          template <class Ty> auto operator()(Ty j)         {             return i - j;         }     };     g = Lambda2(i);     g(1); } 

И в заключение.
Чтобы приведённые примеры кода скомпилировались достаточно заменить auto g на std::function<int(int)> g.
(Как работает std::function — это уже тема для отдельной статьи.)


ссылка на оригинал статьи https://habr.com/ru/post/691028/

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *