Bruce Eckel's Thinking in C++, 2nd Ed | Contents | Prev | Next |
//: C19:applySequence.h // Apply a function to an STL sequence container // 0 arguments, any type of return value: template<class Seq, class T, class R> void apply(Seq& sq, R (T::*f)()) { typename Seq::iterator it = sq.begin(); while(it != sq.end()) { ((*it)->*f)(); it++; } } // 1 argument, any type of return value: template<class Seq, class T, class R, class A> void apply(Seq& sq, R(T::*f)(A), A a) { typename Seq::iterator it = sq.begin(); while(it != sq.end()) { ((*it)->*f)(a); it++; } } // 2 arguments, any type of return value: template<class Seq, class T, class R, class A1, class A2> void apply(Seq& sq, R(T::*f)(A1, A2), A1 a1, A2 a2) { typename Seq::iterator it = sq.begin(); while(it != sq.end()) { ((*it)->*f)(a1, a2); it++; } }
//: C19:Gromit.h // The techno-dog. Has member functions // with various numbers of arguments. #include <iostream> class Gromit { int arf; public: Gromit(int arf = 1) : arf(arf + 1) {} void speak(int) { for(int i = 0; i < arf; i++) std::cout << "arf! "; std::cout << std::endl; } char eat(float) { std::cout << "chomp!" << std::endl; return 'z'; } int sleep(char, double) { std::cout << "zzz..." << std::endl; return 0; } void sit(void) {}
//: C19:applyGromit.cpp // Test applySequence.h #include "Gromit.h" #include "applySequence.h" #include <vector> #include <iostream> using namespace std; int main() { vector<Gromit*> dogs; for(int i = 0; i < 5; i++) dogs.push_back(new Gromit(i)); apply(dogs, &Gromit::speak, 1); apply(dogs, &Gromit::eat, 2.0f); apply(dogs, &Gromit::sleep, 'z', 3.0); apply(dogs, &Gromit::sit);