Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class MadLadPrinter {
- public:
- void print_time(int mins, double secs); // <- this will get called
- void print_time(int mins);
- };
- ...
- MadLadPrinter mlp;
- PrinterLibrary::print_time(mlp); // calls 'mlp.print_time(int, double)'
- #include <iostream>
- // custom struct to ensure functions are called in the correct order
- template<int N>
- struct Precedence : public Precedence<N - 1> {};
- template<>
- struct Precedence<0> {};
- // The main printer that delegates function calls of other classes.
- // Its 'print' function accepts classes that have defined:
- // - void print_time(int mins, double secs)
- // - void print_time(double total_secs)
- // - void print_time(int mins)
- // or none of the above.
- class PrinterDelegator {
- public:
- // The Precedence variable ensures the function with the highest 'N' value
- // gets called. If the function with the current 'N' value is ill-formed,
- // the Precedence struct will cast to its next highest base class until
- // a properly formed function is available.
- template<typename T>
- void print(const T &printer) {
- print(printer, p_);
- }
- private:
- // these would all actually be incrementing
- int mins_{3};
- double secs_{22.5};
- double total_secs_{202.5};
- Precedence<3> p_{};
- // The "best" function. Call this if available
- template<typename T>
- auto print(const T &printer, const Precedence<3>&) -> decltype(printer.print_time(mins_, secs_)) {
- printer.print_time(mins_, secs_);
- }
- // Other available functions ordered by importance
- template<typename T>
- auto print(const T &printer, const Precedence<2>&) -> decltype(printer.print_time(total_secs_)) {
- printer.print_time(total_secs_);
- }
- template<typename T>
- auto print(const T &printer, const Precedence<1>&) -> decltype(printer.print_time(mins_)) {
- printer.print_time(mins_);
- }
- // default empty definition allowing for classes that haven't defined 'print_time'
- template<typename T>
- auto print(const T &printer, const Precedence<0>&) -> decltype(void()) {
- std::cout << "nothing" << std::endl;
- }
- };
- // class with all possible functions. Only the "best"
- // one will get called: 'void print_time(int, double)'
- class VerbosePrinter {
- public:
- void print_time(int mins, double secs) const {
- print_time(mins);
- print_time(secs);
- }
- void print_time(double total_secs) const {
- std::cout << total_secs << "s" << std::endl;
- }
- void print_time(int mins) const {
- std::cout << mins << "m" << std::endl;
- }
- };
- // Class with two of the function options. The best one here is
- // 'void print_time(double)' so that one will be called
- class SinglePrinter {
- public:
- void print_time(double total_secs) const {
- std::cout << total_secs << "s" << std::endl;
- }
- void print_time(int mins) const {
- std::cout << mins << "m" << std::endl;
- }
- };
- // Empty class that can still be used even though no functions are defined
- class EmptyPrinter {};
- int main() {
- PrinterDelegator pd;
- VerbosePrinter vp;
- std::cout << "Should print minutes and seconds:" << std::endl;
- pd.print(vp);
- SinglePrinter sp;
- std::cout << "Should print total seconds:" << std::endl;
- pd.print(sp);
- EmptyPrinter ep;
- std::cout << "Should print nothing:" << std::endl;
- pd.print(ep);
- return 0;
- }
- Precedence
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement