#include #include #include #include /* requires -std=c++14 */ using namespace std; /* CLOSURES PROGRAMMING ASSIGNMENT, PART II Unlike with languages such as Python and Java, C/C++ programmers must be keenly aware of where in memory their data are stored, and of their LIFETIME. The lifetime of a value is how long it's guaranteed to be at the same location in memory. The lifetime ends when, for example, a value gets popped from the stack at the end of a function call, or deallocated from the heap. The value may persist in memory momentarily after its lifetime ends but is unusable as it will be overwritten. ... */ // SOLUTION: key is to first capture name, balance by value so they're // copied into closure before getting popped from the stack. But under // this context, the deposit, withdraw and balinquiry functions must capture // balance by reference. So all that's needed is to define these "methods" // inside the public_interface function instead of outside. In addition, // the public_interface must be marked mutable because it contains // procedures that mutate the free variable balance. (The balance in the // public_interface closure cannot be const). auto newaccount = [](string name, double balance) { auto public_interface = [=](const string& request) mutable { function balinquiry = [&name,&balance]() { printf("%s has a balance of %.2f\n",name.c_str(),balance); return balance; }; function deposit = [&balance](double amt) mutable { if (amt>0) balance+=amt; }; // mutable means function could mutate free variables function withdraw = [&balance](double amt) mutable { if (amt>0 && amt<=balance) balance-=amt; }; function dummyfun = [&balance](double x) mutable {balance+=0;}; if (request=="deposit") { return deposit; } else if (request=="withdraw") { return withdraw; } else if (request=="inquiry") { balinquiry(); } return dummyfun; // this is required for type-consistency }; return public_interface; };//newaccount int main() { auto myaccount = newaccount("Liang",1000); auto youraccount = newaccount("Student",2000); myaccount("inquiry"); // SHOULD print Liang has a balance of 1000 youraccount("inquiry"); // SHOULD print Student has a balance of 2000 myaccount("withdraw")(300); myaccount("deposit")(100); myaccount("inquiry"); // SHOULD print Liang has a balance of 800 return 0; }//main