[随手写写] 减少代码的“复制粘贴”——关于函数

写点啥?

最近状态其实一直挺差的,有各种各样的破事,人很烦躁的说,希望早点能调整过来吧。这学期基本上不怎么更新博客了,一个是学的内容,语言向的多一些,直接写的话很像抄书,对自己的提升基本没有。我对自己的记性还是有点信心的,记忆方面一向不出什么大问题。其实也是自己暗地里开过很多想写的内容,不过都被懒癌战胜了,有点难过。决定还是找个小一点的东西写写,找找感觉。在群博看到了一篇博客,决定拿这个入口搞一下。

在这里:http://blog.csdn.net/sanjiye/article/details/78766542

说什么?

很多时候都有这样的情况:有若干个结构形状极其相似的函数,但是由于这些函数有那么些微小的差别,因而有的时候会考虑直接复制粘贴一份出来,修改那么一小点内容。类似这样的代码:

int io_write_users() {
    FILE *fp = fopen(IO_FILE_USER, IO_MODE_WRITE);

    if (fp == NULL) {
        return -1;
    }

    LINKLIST_ITER(g_user) {
        io_write_any_struct(fp, pi->data, sizeof(user_t));
    }

    fflush(fp);
    fclose(fp);
}

int io_write_play() {
    FILE *fp = fopen(IO_FILE_PLAY, IO_MODE_WRITE);

    if (fp == NULL) {
        return -1;
    }

    LINKLIST_ITER(g_play) {
        io_write_any_struct(fp, pi->data, sizeof(play_t));
    }

    fflush(fp);
    fclose(fp);
}

// 此处省略其余类似的代码……

这些函数都有这类似于:

int io_write_${STRUCT NAME}() {
    FILE *fp = fopen(${FILENAME}, IO_MODE_WRITE);
    if (fp == NULL) {
        return -1;
    }

    LINKLIST_ITER(${LINKLIST NAME}) {
        io_write_any_struct(fp, pi->data, ${SIZEOF STRUCT});
    }

    fflush(fp);
    fclose(fp);
}

这样的结构,这些内容实际上都可以将之提取为一个公用模板:

int io_write(const char *filename, const int dsize, linklist_t *ll) {
    FILE *fp = fopen(filename, IO_MODE_WRITE);

    if (fp == NULL) {
        return -1;
    }

    LINKLIST_ITER((*ll)) {
        io_write_any_struct(fp, pi->data, dsize);
    }

    fflush(fp);
    fclose(fp);
    return 0;
}

然后我们使用宏来还原之前的功能就好,类似于:

#define io_write_user io_write(IO_FILE_USER, sizeof(user_t), &g_user)

或者我们使用C++的函数容器:

const std::function<int()> io_write_user = []()
{ 
    return io_write(IO_FILE_USER, sizeof(user_t), &g_user)
};

还可以更方便一点吗?

上面最后我们用到函数容器,还是用了Lambda表达式,还是得手写一层壳。这里我就想要一个函数的生产机器,怎么办呢?

下面是一个两个进程交替打印数字的程序:

#include<iostream>
#include<mutex>
#include<thread>
#include<functional>
#include<condition_variable>

using namespace std;

mutex mtx;
condition_variable cond;

function<void()> generate(string identifier, function<bool(int)> judgement, int *val, int to)
{
    return [=]()
    {
        while (*val <= to) {
            unique_lock<mutex> lock(mtx);
            if (judgement(*val)) {
                cout << identifier << ": " << (*val)++ << endl;
                cond.notify_all();
            } else {
                cond.wait(lock);
            }
        }
    };
}

int main(int argc, char *argv[])
{
    int val = 1;
    const auto fa = generate("Thread A", [](int val) { return val & 1; }, &val, 10),
               fb = generate("Thread B", [](int val) { return !(val & 1); }, &val, 10);

    thread a(fa), b(fb);

    a.join();
    b.join();

    return 0;
}

在这个代码中,Generate函数就直接地产生了一个新的函数。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值