January 2019
Intermediate to advanced
512 pages
14h 5m
English
Some decorators are very specific to the classes they modify, and their behavior is narrowly targeted. Others are very general, at least in principle. For example, a debugging decorator that logs function calls and prints return values could be used with any function if we could only implement it correctly.
Such an implementation is pretty straightforward in C++14 or above using variadic templates, parameter packs, and perfect forwarding:
template <typename Callable> class DebugDecorator { public: DebugDecorator(const Callable& c, const char* s) : c_(c), s_(s) {} template <typename ... Args> auto operator()(Args&& ... args) const { cout << "Invoking " << s_ << endl; auto res = c_(std::forward<Args>(args) ...