LINUX.ORG.RU

История изменений

Исправление quasimoto, (текущая версия) :

Нестатический метод класса в C++ это тоже пример замыкания (lambda с captures — частный случай, то есть функциональный объект у которого operator() это нестатический метод).

/*
(define new-withdraw
  (let ((balance 100))
    (lambda (amount)
      (if (>= balance amount)
          (begin (set! balance (- balance amount))
                 balance)
          "Insufficient funds"))))
*/

#include <memory>
#include <functional>
#include <iostream>

int main()
{

    /* As method. */

    {

        class NewWithdraw {
            
            int balance = 100;

        public:

            // Non-static method == closure over `balance`.
            int withdraw(const int amount) {
                return
                    balance >= amount
                    ? balance -= amount
                    : throw "Insufficient funds";
            }

        };

        NewWithdraw nw;

        // Proper functional object from class object and its method.
        auto withdraw = std::bind(&NewWithdraw::withdraw, &nw, std::placeholders::_1);
        try {
            // Call method.
            std::cout << nw.withdraw(50) << std::endl;
            // Call functional object (class object already captured).
            std::cout << withdraw(100) << std::endl;
        } catch(char const* error) {
            std::cout << error << std::endl;
        }

    }

    /* As lambda. */

    auto new_withdraw = []() {

        std::shared_ptr<int> balance(new int(100));

        // Lambda with captures == closure over `balance` again.
        return [=](const int amount) {
            return
                *balance >= amount
                ? *balance -= amount
                : throw "Insufficient funds";
        };

    };

    auto withdraw = new_withdraw();
    try {
        std::cout << withdraw(50) << std::endl;
        std::cout << withdraw(100) << std::endl;
    } catch(char const* error) {
        std::cout << error << std::endl;
    }

}

Исправление quasimoto, :

Нестатический метод класса в C++ это тоже пример замыкания (lambda с captures — частный случай, то есть функциональный объект у которого operator() это нестатический метод).

/*
(define new-withdraw
  (let ((balance 100))
    (lambda (amount)
      (if (>= balance amount)
          (begin (set! balance (- balance amount))
                 balance)
          "Insufficient funds"))))
*/

#include <memory>
#include <functional>
#include <iostream>

int main()
{

    /* As method. */

    {

        class NewWithdraw {
            
            int balance = 100;

        public:

            // Non-static method == closure over `balance`.
            int withdraw(const int amount) {
                return
                    balance >= amount
                    ? balance -= amount
                    : throw "Insufficient funds";
            }

        };

        NewWithdraw nw;

        // Proper functional object from class object and its method.
        auto withdraw = std::bind1st(std::mem_fn(&NewWithdraw::withdraw), &nw);

        try {
            // Call method.
            std::cout << nw.withdraw(50) << std::endl;
            // Call functional object (class object already captured).
            std::cout << withdraw(100) << std::endl;
        } catch(char const* error) {
            std::cout << error << std::endl;
        }

    }

    /* As lambda. */

    auto new_withdraw = []() {

        std::shared_ptr<int> balance(new int(100));

        // Lambda with captures == closure over `balance` again.
        return [=](const int amount) {
            return
                *balance >= amount
                ? *balance -= amount
                : throw "Insufficient funds";
        };

    };

    auto withdraw = new_withdraw();
    try {
        std::cout << withdraw(50) << std::endl;
        std::cout << withdraw(100) << std::endl;
    } catch(char const* error) {
        std::cout << error << std::endl;
    }

}

Исходная версия quasimoto, :

Нестатический метод класса в C++ это тоже пример замыкания (lambda с captures — частный случай, то есть функциональный объект у которого operator() это нестатический метод).

/*
(define new-withdraw
  (let ((balance 100))
    (lambda (amount)
      (if (>= balance amount)
          (begin (set! balance (- balance amount))
                 balance)
          "Insufficient funds"))))
*/

#include <memory>
#include <functional>
#include <iostream>

int main()
{

    /* As object. */

    {

        class NewWithdraw {
            
            int balance = 100;

        public:

            // Non-static method == closure over `balance`.
            int withdraw(const int amount) {
                return
                    balance >= amount
                    ? balance -= amount
                    : throw "Insufficient funds";
            }

        };

        NewWithdraw nw;

        // Proper functional object from class object and its method.
        auto withdraw = std::bind1st(std::mem_fn(&NewWithdraw::withdraw), &nw);

        try {
            // Call method.
            std::cout << nw.withdraw(50) << std::endl;
            // Call functional object (class object already captured).
            std::cout << withdraw(100) << std::endl;
        } catch(char const* error) {
            std::cout << error << std::endl;
        }

    }

    /* As lambda. */

    auto new_withdraw = []() {

        std::shared_ptr<int> balance(new int(100));

        // Lambda with captures == closure over `balance` again.
        return [=](const int amount) {
            return
                *balance >= amount
                ? *balance -= amount
                : throw "Insufficient funds";
        };

    };

    auto withdraw = new_withdraw();
    try {
        std::cout << withdraw(50) << std::endl;
        std::cout << withdraw(100) << std::endl;
    } catch(char const* error) {
        std::cout << error << std::endl;
    }

}