//: C05:ApplySequence.h // Apply a function to an STL sequence container. // const, 0 arguments, any type of return value: template<class Seq, class T, class R> void apply(Seq& sq, R (T::*f)() const) { typename Seq::iterator it = sq.begin(); while(it != sq.end()) ((*it++)->*f)(); } // const, 1 argument, any type of return value: template<class Seq, class T, class R, class A> void apply(Seq& sq, R(T::*f)(A) const, A a) { typename Seq::iterator it = sq.begin(); while(it != sq.end()) ((*it++)->*f)(a); } // const, 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) const, A1 a1, A2 a2) { typename Seq::iterator it = sq.begin(); while(it != sq.end()) ((*it++)->*f)(a1, a2); } // Non-const, 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)(); } // Non-const, 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); } // Non-const, 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); } // Etc., to handle maximum likely arguments ///:~
Listado 6.23. C05/ApplySequence.h
//: C05:Gromit.h // The techno-dog. Has member functions // with various numbers of arguments. #include <iostream> class Gromit { int arf; int totalBarks; public: Gromit(int arf = 1) : arf(arf + 1), totalBarks(0) {} void speak(int) { for(int i = 0; i < arf; i++) { std::cout << "arf! "; ++totalBarks; } std::cout << std::endl; } char eat(float) const { std::cout << "chomp!" << std::endl; return 'z'; } int sleep(char, double) const { std::cout << "zzz..." << std::endl; return 0; } void sit() const { std::cout << "Sitting..." << std::endl; } }; ///:~
Listado 6.24. C05/Gromit.h
//: C05:ApplyGromit.cpp // Test ApplySequence.h. #include <cstddef> #include <iostream> #include <vector> #include "ApplySequence.h" #include "Gromit.h" #include "../purge.h" using namespace std; int main() { vector<Gromit*> dogs; for(size_t 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); purge(dogs); } ///:~
Listado 6.25. C05/ApplyGromit.cpp