C++模仿python的装饰器功能

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机制。

反正,还得一大堆事儿。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值