1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
| #include <iostream> #include <functional> #include "stdarg.h"
struct Logger { std::function<void()> func; std::string name;
Logger(const std::function<void()>&func, const std::string& name) : func{func}, name{name} {}
void operator()() const { std::cout << "Entering " << name << "\n"; func(); std::cout << "Exiting " << name << "\n"; }
};
template <typename Func> struct Logger2 { Func func; std::string name;
Logger2(const Func& func, const std::string& name) : func{func}, name{name} {}
void operator()() const { std::cout << "Entering" << name << std::endl; func(); std::cout << "Exiting" << name << std::endl; } };
template <typename Func> auto make_logger2(Func func, const std::string& name) { return Logger2<Func>{ func, name }; }
double add(double a, double b) { std::cout << a << "+" << b << "=" << (a + b) << std::endl; return a+b; }
template <typename R, typename... Args> struct Logger3 { Logger3(std::function<R(Args...)> func, const std::string& name) : func{func}, name{name} {}
R operator() (Args ...args) { std::cout << "Entering " << name << std::endl; R result = func(args...); std::cout << "Exiting " << name << std::endl; return result; }
std::function<R(Args...)> func; std::string name; };
template <typename R, typename... Args> auto make_logger3(R (*func)(Args...), const std::string& name) { return Logger3<R, Args...>(std::function<R(Args...)>(func), name); }
int main(void) { Logger([]() { std::cout << "Hello\n"; }, "HelloFunction")();
auto call = make_logger2([]() { std::cout << "Hello!" << std::endl; }, "HelloFunction"); call();
auto logged_add = make_logger3(add, std::string("Add")); auto result = logged_add(2, 3);
return 0; }
|