C++固有语法限制,导致能模仿功能,但是无法模仿语法
function<int (int)> f = [](int x){return x;};
DECORATOR(f, pre, post)
被装饰的函数必须使用function<。。。>类型,然后在函数定义后面,使用DECORATOR宏进行装饰。
如果这个不可接受的话,下面内容也就不用看啦。
装饰函数的示例:
//调用前装饰,要能接受被装饰函数的所有参数,
//可以传拷贝、&、const &,取决于是否要修改这些参数
//返回值为optional<RESULT>或者pair<bool, RESULT>,以便中止调用原函数
optional<int> pre(int &x){ if (x < 10 ) { return -1; } x *= 2; return optional<int>();}
//调用后装饰,要能接受被装饰函数的返回值+所有参数
//可以传拷贝、&、const &,取决于是否要修改返回值或回传参数
void post(int &r, int x){r=r*2;}
装饰器的实现:
template<class F, class PRE, class POST = void (*)(...)>
struct decorator
{
decorator(F& func, PRE && pre, POST && post = POST())
{
func = [func = std::move(func), pre=std::move(pre), post=std::move(post)](auto&&... args)
{
std::cout << "Beginning decorating...\n";
if (pre)
{
std::cout << "pre decorating...\n";
auto preResult = pre(args...);//可以修改入参
if (preResult)
{
std::cout << "pre decorate failed\n";
return std::move(*preResult);
}
}
std::cout << "origin calling...\n";
auto result = func(std::forward<decltype(args)>(args)...);
if (post)
{
std::cout << "post decorating...\n";
post(result, args...);
}
std::cout << "END decorating\n";
return result;
};
}
};
#define DECORATOR(f, decorators...)\
auto decorator##__FILE__##__LINE__ = decorator(f, ##decorators);
可以试着执行下面代码看看效果:
cout << f(12) << endl;
cout << f(8) << endl;
如果要实用,还得对无参数和无返回值的各种组合做处理,要么decorator类(偏)特化,要么decorator的构造函数使用constexpr机制。
反正,还得一大堆事儿。