写点啥?
最近状态其实一直挺差的,有各种各样的破事,人很烦躁的说,希望早点能调整过来吧。这学期基本上不怎么更新博客了,一个是学的内容,语言向的多一些,直接写的话很像抄书,对自己的提升基本没有。我对自己的记性还是有点信心的,记忆方面一向不出什么大问题。其实也是自己暗地里开过很多想写的内容,不过都被懒癌战胜了,有点难过。决定还是找个小一点的东西写写,找找感觉。在群博看到了一篇博客,决定拿这个入口搞一下。
说什么?
很多时候都有这样的情况:有若干个结构形状极其相似的函数,但是由于这些函数有那么些微小的差别,因而有的时候会考虑直接复制粘贴一份出来,修改那么一小点内容。类似这样的代码:
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函数就直接地产生了一个新的函数。