Объяснить термин "замыкание" и код

Hunter13ua

Замыкание (англ. closure) в программировании — функция, в теле которой присутствуют ссылки на переменные, объявленные вне тела этой функции и не в качестве её параметров (а в окружающем коде). Говоря другим языком, замыкание — функция, которая ссылается на свободные переменные в своём контексте.
Прочитал и всё равно ничего не понял. Даже код не помог. Прошу объяснить.
function<int()> f() {
        int x = 0;
        return [=] () mutable {return ++x; };
}
 
auto fun = f();
for (int i = 0; i < 5; ++i) {
        cout << fun() << endl;
}
10 ответов

Hunter13ua

Замыкание (англ. closure) в программировании — функция, в теле которой присутствуют ссылки на переменные, объявленные вне тела этой функции и не в качестве её параметров (а в окружающем коде).
Может я ошибаюсь, но глобальные переменные полностью подходят для этой формулировки


Hunter13ua

Прочитал и всё равно ничего не понял. Даже код не помог. Прошу объяснить.
Ну оно пока понимать и не нужно для новичков, замыкание это когда вызывается функция в которую передаются ссылки без копирования, в общем если мы возьмем выражение a=b+c+d то мы его можем записать как a.operator=(b.operator+(c.operator+(d))); operator+ будет вызват 1 временных объекта, что бы этого не было используют такой механизм как замыкание, создается функция допустим int int_plac_int_plac(int& a, int& b, int& c); и уже для подсчета суммы трех переменных используется эта оптимизированная функция a=int_plac_int_plac(b,c,d); в которой объекты ссылки, получается мы замкнули 3 объекта в одном объекте и просто там уже создаем уже одну копию без создания промежуточного временного объекта. Замыкание это в общем можно сказать передача функции по ссылке нескольких объектов, а практическое применение видимо используется для оптимизации кода. Новичкам это замыкание и нафиг не здалось, это нужно разработчикам библиотек. Программисты делятся на разработчиков классов и прикладных разработчиков тех которые используют классы, от как раз в разработке классов это и используется для оптимизации. Для прикладных программистов, а таких я думаю процентов 90 из всех, 10% токо разрабатывают классы и либы ИМХО, им оно и нафиг не здалось им более важны знания области для которой они создают программы. Так что не знаешь и забей на это, лучше изучай область своей разработки.


Hunter13ua

Hunter13ua, Что именно не понятно? Мы создаем лямбду, которая захватывает из внешнего контекста копию переменной x и благодаря mutable мы можем изменять эту копию переменной внутри лямбды.
auto fun = f();
for (int i = 0; i < 5; ++i) {
        cout << fun() << endl;
}
На момент инициализации fun у нас уже нету переменной x, которая созданна в функции f, а есть только ее копия в лямбде.
Программисты делятся на разработчиков классов и прикладных разработчиков тех которые используют классы, от как раз в разработке классов это и используется для оптимизации. Для прикладных программистов, а таких я думаю процентов 90 из всех, 10% токо разрабатывают классы и либы ИМХО, им оно и нафиг не здалось им более важны знания области для которой они создают программы. Так что не знаешь и забей на это, лучше изучай область своей разработки.
Что я только что прочитал? То есть программисты, пишущие на С++, НЕ разрабатывают классы?


Hunter13ua

Что я только что прочитал? То есть программисты, пишущие на С++, НЕ разрабатывают классы?
Ну я имел введу программисты которые создают библиотеки, наборы классов и тех которые используют эти классы. Для вторых оптимизация редко когда нужна, а первым важно создавать правильный быстрый код, ну и если программист ссылки будет использовать и не знать что это замыкание, то ничего страшного.
a.operator=(b.operator+(c.operator+(d)))
Тут я чуток ошибся нужно заменить на a.operator=(operator+(b,operator+(c,d)));Вообще мой примерчик самый понятный, плюс практическая польза оптимизация кода!


Hunter13ua

ninja2, Это НЕ является замыканием. Ссылка это ссылка. closure это closure. Дабы понять, что Ваш пример не имеет никакого отношения к замыканию достаточно процитировать вот это:
функция, в теле которой присутствуют ссылки на переменные, объявленные вне тела этой функции и не в качестве её параметров (а в окружающем коде).
Ну и можно ведь было почитать википедию дальше, где все объясняется...
Замыкание — это особый вид функции. Она определена в теле другой функции и создаётся каждый раз во время её выполнения. В записи это выглядит как функция, находящаяся целиком в теле другой функции. При этом вложенная внутренняя функция содержит ссылки на локальные переменные внешней функции. Каждый раз при выполнении внешней функции происходит создание нового экземпляра внутренней функции, с новыми ссылками на переменные внешней функции. В случае замыкания ссылки на переменные внешней функции действительны внутри вложенной функции до тех пор, пока работает вложенная функция, даже если внешняя функция закончила работу, и переменные вышли из области видимости. Замыкание связывает код функции с её лексическим окружением (местом, в котором она определена в коде). Лексические переменные замыкания отличаются от глобальных переменных тем, что они не занимают глобальное пространство имён. От переменных в объектах они отличаются тем, что привязаны к функциям, а не объектам.


Hunter13ua

Это НЕ является замыканием. Ссылка это ссылка. closure это closure. Дабы понять, что Ваш пример не имеет никакого отношения к замыканию достаточно процитировать вот это:
Тот пример что я привел он в книге описан "Язык С++" Страуструп и именно это называли замыкание, цитировать неохота, а википедия недостоверный источник. Я помню еще где то в своей теме приводил пример из книги и цитировал, там со мной кто то не соглашался, говорил что это не замыкание, короче доказал что я прав и это есть замыкание!А от токо вспомнил что там было, что называли замыканием, это я чуточку перепутал, ну оно похоже тоже самое.От мы прибавляем a=b+c-d, у нас не функция вызывается которая принимает 3 ссылки, а b+c создает новый объект в котором содержаться ссылки на b и с и уже a=новый_объект-d и это в программировании называется замыканием отак было, то я уже чуток перекрутил, отета фигня наоборот все запутывает. А если у нас будет 3 операции перегружены для класса и нам нужно будет например посчитать выражение a=b+c-d+e, оно автоматически приобразуется к выражению a=новый_объект_1+новый_объект_2, и что это означает? Понятно что минус 2 временных объекта. Еще раз говорю это для создателей библиотек важно как можно оптимизировать код, сделать его более быстрым, менее затратным, обычным прикладным программистам оно и нафиг не здалось ИМХО. Создавать библиотеки вы дулю где устроитесь, будете писать прикладные проги, даже обобщенное программирование наврятле где нить будет ИМХО, так что не партесь.


Hunter13ua

ninja2, Уважаемый, разбирайтесь в терминах пожалуйста. Замыкание это термин функционального программирования. Вот например замыкание
def counter():
    x = 0
    def increment(y):
        nonlocal x
        x += y
        print(x)
    return increment
Функция возвращает функцию, которая определена в этой функции и оперирует с локальными данными этой функции.http://stackoverflow.com/questions/36636/what-is-a-closure


Hunter13ua

От мы прибавляем a=b+c-d, у нас не функция вызывается которая принимает 3 ссылки, а b+c создает новый объект в котором содержаться ссылки на b и с и уже a=новый_объект-d и это в программировании называется замыканием
) с чего ты так решил? При чём тут вообще замыкание?)


Hunter13ua

Уважаемый, разбирайтесь в терминах пожалуйста. Замыкание это термин функционального программирования. Вот например замыкание
Нет я при своем мнении останусь, при своем понятии этого термина.


Hunter13ua

ninja2, Браво. Успешной работы программистом Вам.