用C++ Variadic Template 和 lambda表达式简化判断函数返回值的语句

本文介绍如何使用C++的变长模板参数和Lambda表达式来简化socket编程中的错误处理过程。通过一个通用的check函数,可以针对不同函数及其错误条件进行统一的错误检查。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在socket编程中,经常会需要判断某函数是否成功,若不成功,则退出的操作。
如:
if (socket( domain , type,  protocol  ) == -1) {
    exit(-1);
}
为了不用每次调用socket都加上这句判断,可以将这种函数封装,调用封装函数。

void checkSocket(int domain, int type, int protocol) {
if (socket( domain , type,  protocol ) == -1) {
    exit(-1);
}
}

但问题是像这种函数有不少,如connect、listen等等。每个函数的参数也会有不同,且错误条件不同,有的是返回-1,有的是返回小于0的数。每个函数都去封装一次还是很麻烦。

利用C++变长模板参数和lambda表达式可以比较方便的解决问题,大体想法如下所示。

template <typename F, typename Cond, typename... Args>
void check(F f, Cond cond, Args... args) {
if (cond(f(args...))) {
cout << "error!\n";
}
}

int openFile(int, int, int) {
return -1;
}

int openSocket(int, const char*) {
return -2;
}

int main()
{
check(openFile, [](int x) {return x == -1;}, 1, 1, 1);
check(openSocket, [](int x) {return x < 0;}, 1, "aha");
        return 0;
}

openFile和openSocket是两个参数类型、数量以及返回值都不同的函数,我们想实现的操作时
if (openFile(x, y, z) == -1) {
    cout << "error";
}
以及
if (openSocket(x, y) == -2) {
    cout << "error";
}
本来需要封装两次的,但现在只需要checkF就只需要封装一次即可。
checkF有三个模板类型,F、Cond以及“类型包”Args。
F是待封装的函数,如openFile;
Cond是测试调价,如 "== -1",可以是函数指针或者是C++中的函数对象,也可以是C++11引入的lambda表达式(lambda表达式是匿名函数);
Args是F的所有参数,长度可变,当我们调用
check(openFile, [](int x) {return x == -1;}, 1, 1, 1);
时,编译器将把Args处理为三个int类型的参数,并在
if (cond(f(args...))) 
中传给f。

上面方法的不足之处在于,checkF对失败的处理都是一样的(cout << "error\n";),
有时候需要不一样的处理。可以考虑再加入一个参数。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值