c++ 泛型装饰器


本文简单写了个 c++ 装饰器
主要使用的是c++ lamda 表达式
结合完美转发技巧,在一定程度上提升性能

实例一介绍了一个相对通用的例子

实例二:场景是这样的, 我们希望统计某项工作的耗时, 但是不想修改相关的代码
这时候装饰器就可以登场了, 装饰关系如下, 左边的被右边的装饰, 这个和 java spring 面向切面编程有些相似;
time_beign 被装饰 -> work 被装饰-> time_end 被装饰 -> time_cost

通用代码一

#define FieldSetter(name, type, field) \
    type field;                                   \
    name() {}                   \
    name(const type& field): field(field) { \
        cout << "[左值 " << field << "]" << endl;                                   \
    } \
    name(const type&& field) : field(move(field)){ \
        cout << "[右值 " << field << "]" <<  endl; \
    } \
    name(const name& other) {          \
         field = other.field; \
         cout << "[左值 " << other.field << "]" << endl;                          \
    } \
    name(const name&& other) {         \
        field = move(other.field);                             \
          cout << "[右值 " << other.field << "]" <<  endl; \
    }

struct ObjectField {
    FieldSetter(ObjectField, string, name);
};

struct AgeField {
    FieldSetter(AgeField, int, age);
};

struct SexField {
    FieldSetter(SexField, string, sex);
};

void DecoratorTest() {
    auto Object = [](auto ob) {
        cout << ob.name << endl;
    };
    auto Age = [](auto age) {
        cout << age.age << endl;
    };
    auto sex = [](auto sex) {
        cout << sex.sex << endl;
    };

    auto withDecorator = [](auto &&head, auto &&tail, auto &&...hargs) {
        head(forward<decltype(hargs)>(hargs)...);
        return [f = std::move(tail)](auto &&...args) {
            return f(forward<decltype(args)>(args)...);
        };
    };

    auto nameWithAge = withDecorator(Object, Age, ObjectField("nic"));
    auto withDecoratorWithSex = withDecorator(nameWithAge, sex, AgeField(18));
    withDecoratorWithSex(SexField("man"));
}

int main() {
    DecoratorTest();
}

输出

在这里插入图片描述
对输出的解释
[左值 ] 表示传参的过程中调用了拷贝构造函数
[右值 ] 表示在传参过程中调用的是 移动构造函数

测试用例二

auto withDecorator = [](auto &&head, auto &&tail, auto &&...hargs) {
    return [&,f = std::move(tail)](auto &&...args) {
        head(forward<decltype(hargs)>(hargs)...);
        return f(forward<decltype(args)>(args)...);
    };
};

long Now() {
    struct timeval s;
    gettimeofday(&s, NULL);
    return s.tv_sec * 1e6 + s.tv_usec;
}

struct TimeElapse {
    long before;
    long after;
};

auto timeBegin = [](TimeElapse &ts) {
    cout << "time begin" << endl;
    ts.before = Now();
};

auto work = [](auto &&...strs) {
    if (sizeof ...(strs) == 0) {
        return;
    }
    cout << "work: ";
    (cout << ... << strs);
    cout << endl;
};

auto timeEnd = [](TimeElapse &ts) {
    cout << "time end" << endl;
    ts.after = Now();
};

auto timeCost = [](TimeElapse &ts) {
    cout << "total cost " << ts.after - ts.before << endl;
};

int main() {
    TimeElapse ts;
    auto tb = withDecorator(timeBegin, work, ts);
    auto te = withDecorator(tb, timeEnd, 1, 2, 3, 4, 5, 6, 7, 8);
    auto tc = withDecorator(te, timeCost, ts);
    tc(ts);
}

输出

在这里插入图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值