//: C06:Counted.h // An object that keeps track of itself. #ifndef COUNTED_H #define COUNTED_H #include <vector> #include <iostream> class Counted { static int count; char* ident; public: Counted(char* id) : ident(id) { ++count; } ~Counted() { std::cout << ident << " count = " << --count << std::endl; } }; class CountedVector : public std::vector<Counted*> { public: CountedVector(char* id) { for(int i = 0; i < 5; i++) push_back(new Counted(id)); } }; #endif // COUNTED_H ///:~
Listado 7.39. C06/Counted.h
//: C06:ForEach.cpp {-mwcc} // Use of STL for_each() algorithm. //{L} Counted #include <algorithm> #include <iostream> #include "Counted.h" using namespace std; // Function object: template<class T> class DeleteT { public: void operator()(T* x) { delete x; } }; // Template function: template<class T> void wipe(T* x) { delete x; } int main() { CountedVector B("two"); for_each(B.begin(), B.end(), DeleteT<Counted>()); CountedVector C("three"); for_each(C.begin(), C.end(), wipe<Counted>); } ///:~
Listado 7.40. C06/ForEach.cpp
//: C06:Transform.cpp {-mwcc} // Use of STL transform() algorithm. //{L} Counted #include <iostream> #include <vector> #include <algorithm> #include "Counted.h" using namespace std; template<class T> T* deleteP(T* x) { delete x; return 0; } template<class T> struct Deleter { T* operator()(T* x) { delete x; return 0; } }; int main() { CountedVector cv("one"); transform(cv.begin(), cv.end(), cv.begin(), deleteP<Counted>); CountedVector cv2("two"); transform(cv2.begin(), cv2.end(), cv2.begin(), Deleter<Counted>()); } ///:~
Listado 7.41. C06/Transform.cpp
//: C06:Inventory.h #ifndef INVENTORY_H #define INVENTORY_H #include <iostream> #include <cstdlib> using std::rand; class Inventory { char item; int quantity; int value; public: Inventory(char it, int quant, int val) : item(it), quantity(quant), value(val) {} // Synthesized operator= & copy-constructor OK char getItem() const { return item; } int getQuantity() const { return quantity; } void setQuantity(int q) { quantity = q; } int getValue() const { return value; } void setValue(int val) { value = val; } friend std::ostream& operator<<( std::ostream& os, const Inventory& inv) { return os << inv.item << ": " << "quantity " << inv.quantity << ", value " << inv.value; } }; // A generator: struct InvenGen { Inventory operator()() { static char c = 'a'; int q = rand() % 100; int v = rand() % 500; return Inventory(c++, q, v); } }; #endif // INVENTORY_H ///:~
Listado 7.42. C06/Inventory.h
//: C06:CalcInventory.cpp // More use of for_each(). #include <algorithm> #include <ctime> #include <vector> #include "Inventory.h" #include "PrintSequence.h" using namespace std; // To calculate inventory totals: class InvAccum { int quantity; int value; public: InvAccum() : quantity(0), value(0) {} void operator()(const Inventory& inv) { quantity += inv.getQuantity(); value += inv.getQuantity() * inv.getValue(); } friend ostream& operator<<(ostream& os, const InvAccum& ia) { return os << "total quantity: " << ia.quantity << ", total value: " << ia.value; } }; int main() { vector<Inventory> vi; srand(time(0)); // Randomize generate_n(back_inserter(vi), 15, InvenGen()); print(vi.begin(), vi.end(), "vi"); InvAccum ia = for_each(vi.begin(),vi.end(), InvAccum()); cout << ia << endl; } ///:~
Listado 7.43. C06/CalcInventory.cpp
//: C06:TransformNames.cpp // More use of transform(). #include <algorithm> #include <cctype> #include <ctime> #include <vector> #include "Inventory.h" #include "PrintSequence.h" using namespace std; struct NewImproved { Inventory operator()(const Inventory& inv) { return Inventory(toupper(inv.getItem()), inv.getQuantity(), inv.getValue()); } }; int main() { vector<Inventory> vi; srand(time(0)); // Randomize generate_n(back_inserter(vi), 15, InvenGen()); print(vi.begin(), vi.end(), "vi"); transform(vi.begin(),vi.end(),vi.begin(),NewImproved()); print(vi.begin(), vi.end(), "vi"); } ///:~
Listado 7.44. C06/TransformNames.cpp
//: C06:SpecialList.cpp // Using the second version of transform(). #include <algorithm> #include <ctime> #include <vector> #include "Inventory.h" #include "PrintSequence.h" using namespace std; struct Discounter { Inventory operator()(const Inventory& inv, float discount) { return Inventory(inv.getItem(), inv.getQuantity(), int(inv.getValue() * (1 - discount))); } }; struct DiscGen { float operator()() { float r = float(rand() % 10); return r / 100.0; } }; int main() { vector<Inventory> vi; srand(time(0)); // Randomize generate_n(back_inserter(vi), 15, InvenGen()); print(vi.begin(), vi.end(), "vi"); vector<float> disc; generate_n(back_inserter(disc), 15, DiscGen()); print(disc.begin(), disc.end(), "Discounts:"); vector<Inventory> discounted; transform(vi.begin(),vi.end(), disc.begin(), back_inserter(discounted), Discounter()); print(discounted.begin(), discounted.end(),"discounted"); } ///:~
Listado 7.45. C06/SpecialList.cpp