fork download
  1. #include <iostream>
  2.  
  3. // stub logging object to make the example work - just logs to stdout
  4. struct Log
  5. {
  6. template<typename T>
  7. friend Log& operator<<(Log& l, T d)
  8. {
  9. std::cout << d;
  10. return l;
  11. }
  12. friend Log& operator<<(Log& l, std::ostream& (*f)(std::ostream&))
  13. {
  14. std::cout << f;
  15. return l;
  16. }
  17. };
  18. Log gLog;
  19.  
  20. #define LOG Base::GetLog()
  21.  
  22. // GetLog in the global namespace for non-Context derived classes, free functions etc
  23. struct Base {
  24. static Log& GetLog()
  25. {
  26. return gLog;
  27. }
  28. };
  29.  
  30. // classes derive from this to add context specific information when logging
  31. template <typename Self>
  32. struct Context
  33. {
  34. // this GetLog adds prefix to Context derived classes
  35. Log& GetLog()
  36. {
  37. static_cast<const Self*>(this)->Token(gLog); // add the Context's Token to the log
  38. return gLog << ": ";
  39. }
  40. };
  41.  
  42. //-------------------------
  43.  
  44. template<typename T>
  45. struct Foo : Context<Foo<T>>
  46. {
  47. typedef Context<Foo<T>> Base;
  48.  
  49. void Func1()
  50. {
  51. LOG << __func__ << std::endl;
  52. }
  53. void Func2()
  54. {
  55. LOG << __func__ << std::endl;
  56. }
  57.  
  58. Log& Token(Log& l) const { return l << "Foo"; }
  59. };
  60.  
  61. // logging inside a non-Context derived class
  62. struct Bar
  63. {
  64. void Func()
  65. {
  66. LOG << __func__ << std::endl;
  67. }
  68. };
  69.  
  70. // logging inside a free function
  71. void Baz()
  72. {
  73. LOG << __func__ << std::endl;
  74. }
  75.  
  76. //-------------------------
  77.  
  78. int main()
  79. {
  80. Foo<int> f;
  81. f.Func1();
  82. f.Func2();
  83.  
  84. Bar b;
  85. b.Func();
  86.  
  87. Baz();
  88.  
  89. return 0;
  90. }
Success #stdin #stdout 0s 2896KB
stdin
Standard input is empty
stdout
Foo: Func1
Foo: Func2
Func
Baz