dostarcza większość elementów do mojego proponowanego rozwiązania.
Oto moje proponowane rozwiązanie.
#include <iostream>
#include <functional>
//-------------------------------
// BEGIN decorator implementation
//-------------------------------
template <class> struct Decorator;
template <class R, class... Args>
struct Decorator<R(Args ...)>
{
Decorator(std::function<R(Args ...)> f) : f_(f) {}
R operator()(Args ... args)
{
std::cout << "Calling the decorated function.\n";
return f_(args...);
}
std::function<R(Args ...)> f_;
};
template<class R, class... Args>
Decorator<R(Args...)> makeDecorator(R (*f)(Args ...))
{
return Decorator<R(Args...)>(std::function<R(Args...)>(f));
}
//-------------------------------
// END decorator implementation
//-------------------------------
//-------------------------------
// Sample functions to decorate.
//-------------------------------
// Proposed solution doesn't work with default values.
// int decorated1(int a, float b = 0)
int decorated1(int a, float b)
{
std::cout << "a = " << a << ", b = " << b << std::endl;
return 0;
}
void decorated2(int a)
{
std::cout << "a = " << a << std::endl;
}
int main()
{
auto method1 = makeDecorator(decorated1);
method1(10, 30.3);
auto method2 = makeDecorator(decorated2);
method2(10);
}
wyjściowa:
Calling the decorated function.
a = 10, b = 30.3
Calling the decorated function.
a = 10
PS
Decorator
stanowi miejsce, w którym można dodać funkcjonalność poza podejmowania wywołanie funkcji. Jeśli chcesz prosty przechodzi do std::function
, można użyć:
template<class R, class... Args >
std::function<R(Args...)> makeDecorator(R (*f)(Args ...))
{
return std::function<R(Args...)>(f);
}
Ładny kod, ale za długi. Rozumiem, że to nie jest Py, a C++ nie zapewnia silnego cukru składniowego, takiego jak Py. :) Ale czy można zadeklarować niektóre makra i użyć kodu, jak pokazuję w moich przykładach? Ta dekorowana metoda jest zdefiniowana w środowisku wykonawczym, ale chcę ją wykorzystać we wszystkich innych funkcjach i klasach. Muszę powtórzyć "makeDecorator" wszędzie? Dzięki. :) – Broly
@Broly, tak, będziesz musiał powtarzać wywołania 'makeDecorator()' przynajmniej raz dla każdej funkcji, którą chcesz udekorować. Aby uzyskać sugerowaną jakość produkcji kodu, potrzebujesz trochę pracy. –