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++ всё ещё не поддерживает шаблонные методы в локальных классах.
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/
Добавить комментарий