Advertisement
Guest User

Untitled

a guest
Aug 19th, 2017
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.32 KB | None | 0 0
  1. class MadLadPrinter {
  2. public:
  3. void print_time(int mins, double secs); // <- this will get called
  4. void print_time(int mins);
  5. };
  6. ...
  7. MadLadPrinter mlp;
  8. PrinterLibrary::print_time(mlp); // calls 'mlp.print_time(int, double)'
  9.  
  10. #include <iostream>
  11.  
  12. // custom struct to ensure functions are called in the correct order
  13. template<int N>
  14. struct Precedence : public Precedence<N - 1> {};
  15. template<>
  16. struct Precedence<0> {};
  17.  
  18. // The main printer that delegates function calls of other classes.
  19. // Its 'print' function accepts classes that have defined:
  20. // - void print_time(int mins, double secs)
  21. // - void print_time(double total_secs)
  22. // - void print_time(int mins)
  23. // or none of the above.
  24. class PrinterDelegator {
  25. public:
  26. // The Precedence variable ensures the function with the highest 'N' value
  27. // gets called. If the function with the current 'N' value is ill-formed,
  28. // the Precedence struct will cast to its next highest base class until
  29. // a properly formed function is available.
  30. template<typename T>
  31. void print(const T &printer) {
  32. print(printer, p_);
  33. }
  34.  
  35. private:
  36. // these would all actually be incrementing
  37. int mins_{3};
  38. double secs_{22.5};
  39. double total_secs_{202.5};
  40.  
  41. Precedence<3> p_{};
  42.  
  43. // The "best" function. Call this if available
  44. template<typename T>
  45. auto print(const T &printer, const Precedence<3>&) -> decltype(printer.print_time(mins_, secs_)) {
  46. printer.print_time(mins_, secs_);
  47. }
  48. // Other available functions ordered by importance
  49. template<typename T>
  50. auto print(const T &printer, const Precedence<2>&) -> decltype(printer.print_time(total_secs_)) {
  51. printer.print_time(total_secs_);
  52. }
  53. template<typename T>
  54. auto print(const T &printer, const Precedence<1>&) -> decltype(printer.print_time(mins_)) {
  55. printer.print_time(mins_);
  56. }
  57. // default empty definition allowing for classes that haven't defined 'print_time'
  58. template<typename T>
  59. auto print(const T &printer, const Precedence<0>&) -> decltype(void()) {
  60. std::cout << "nothing" << std::endl;
  61. }
  62. };
  63.  
  64. // class with all possible functions. Only the "best"
  65. // one will get called: 'void print_time(int, double)'
  66. class VerbosePrinter {
  67. public:
  68. void print_time(int mins, double secs) const {
  69. print_time(mins);
  70. print_time(secs);
  71. }
  72. void print_time(double total_secs) const {
  73. std::cout << total_secs << "s" << std::endl;
  74. }
  75. void print_time(int mins) const {
  76. std::cout << mins << "m" << std::endl;
  77. }
  78. };
  79.  
  80. // Class with two of the function options. The best one here is
  81. // 'void print_time(double)' so that one will be called
  82. class SinglePrinter {
  83. public:
  84. void print_time(double total_secs) const {
  85. std::cout << total_secs << "s" << std::endl;
  86. }
  87. void print_time(int mins) const {
  88. std::cout << mins << "m" << std::endl;
  89. }
  90. };
  91.  
  92. // Empty class that can still be used even though no functions are defined
  93. class EmptyPrinter {};
  94.  
  95.  
  96. int main() {
  97. PrinterDelegator pd;
  98.  
  99. VerbosePrinter vp;
  100. std::cout << "Should print minutes and seconds:" << std::endl;
  101. pd.print(vp);
  102.  
  103. SinglePrinter sp;
  104. std::cout << "Should print total seconds:" << std::endl;
  105. pd.print(sp);
  106.  
  107. EmptyPrinter ep;
  108. std::cout << "Should print nothing:" << std::endl;
  109. pd.print(ep);
  110.  
  111. return 0;
  112. }
  113.  
  114. Precedence
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement