首页 \ 问答 \ 功能包装避免重复(wrap of functions avoid duplicating)

功能包装避免重复(wrap of functions avoid duplicating)

我有第三方C库。 我想在c ++中使用它每个函数都返回错误代码。 当我必须使用它时,我必须编写如下代码:

int err;
err=libFun1(....);
check(err);
err=libFun2(....);
check(err);

我想包装这个函数,避免代码重复检查。 每个librabry函数都有不同的数字参数。 什么是好的设计呢?


I have third party C library. I want to use it in c++ Every function return error code. when i have to use it I have to write code like this:

int err;
err=libFun1(....);
check(err);
err=libFun2(....);
check(err);

I want to wrap this functions and avoid code duplication of check. Every of this librabry function have different number parameters. What will be a good design for this?

更新时间:2023-03-21 22:03

最满意答案

/ edit 4:使用可变参数模板的C ++ 11-Way,灵感来自Gill Bates的解决方案:

template <typename T, class ...A> int CallWrapper(T func, A... args) {
    int error = func(args...);
    check(error);
    return error;
}

CallWrapper(libFun1);
CallWrapper(libFun2, 4711);
CallWrapper(libFun3, 42, 23);

/编辑5:从第一个解决方案开始的旧解决方案:

#define LIBFUN1() do { \
    int err = libFun1(); \
    check(err); \
} while (0)

#define LIBFUN2() do { \
    int err = libFun2(); \
    check(err); \
} while (0)

LIBFUN1();
LIBFUN2();

#define放在某个头文件中。 请注意while ()之后的MISSING分号。 这样,您可以在任何上下文中天真地使用LIBFUN1()等,其中允许语句,如if (...) LIBFUN1(); else LIBFUN2(); if (...) LIBFUN1(); else LIBFUN2();

/ edit 3:静态内联函数也可以完成这项工作,而不是使用#define

static inline int checked_libFun1() {
    int err = libFun1();
    check(err);
    return err;
}

static inline int checked_libFun2() {
    int err = libFun2();
    check(err);
    return err;
}

checked_libFun1();
checked_libFun2();

/ edit 2:@Myst建议使用包含要调用的函数名称的可变参数宏。 这看起来像这样:

#define call_void(name) do { \
    int err = name(); \
    check(err); \
} while (0)

#define call_args(name, ...) do { \
    int err = name(__VA_ARGS__); \
    check(err); \
} while (0)

call_void(libFun1);
call_args(libFun2, 42);

需要这两个宏是因为你必须区分不接受任何参数的函数和接受任何数量的参数的函数。 所以,在这里,将调用libFun2(42)


/edit 4: The C++11-Way using variadic templates, inspired by Gill Bates' solution:

template <typename T, class ...A> int CallWrapper(T func, A... args) {
    int error = func(args...);
    check(error);
    return error;
}

CallWrapper(libFun1);
CallWrapper(libFun2, 4711);
CallWrapper(libFun3, 42, 23);

/edit 5: older solutions, beginning with first solution:

#define LIBFUN1() do { \
    int err = libFun1(); \
    check(err); \
} while (0)

#define LIBFUN2() do { \
    int err = libFun2(); \
    check(err); \
} while (0)

LIBFUN1();
LIBFUN2();

Put the #defines in some header file. Please note the MISSING semicolon after the while (). This way, you can naively use LIBFUN1() and so on in any context, where a statement is allowed like if (...) LIBFUN1(); else LIBFUN2();

/edit 3: Instead of using #defines, static inline functions would do the job too:

static inline int checked_libFun1() {
    int err = libFun1();
    check(err);
    return err;
}

static inline int checked_libFun2() {
    int err = libFun2();
    check(err);
    return err;
}

checked_libFun1();
checked_libFun2();

/edit 2: @Myst suggested to use variadic macros that contain the name of the function to call. This could look like this:

#define call_void(name) do { \
    int err = name(); \
    check(err); \
} while (0)

#define call_args(name, ...) do { \
    int err = name(__VA_ARGS__); \
    check(err); \
} while (0)

call_void(libFun1);
call_args(libFun2, 42);

The two macros are needed because you have to distinguish between functions not accepting any arguments and functions accepting any number of arguments greater one. So, here, libFun2(42) would be called

相关问答

更多

相关文章

更多

最新问答

更多
  • 在javascript中创建类以创建对象并在Java中创建类和对象之间的区别(Difference between creating a class in javascript to create an object and creating an class and object in Java)
  • Facebook API:将身份验证详细信息从Javascript SDK发送到PHP SDK(Facebook API: Send authentication detail from Javascript SDK to PHP SDK)
  • 如何停止队列动画jquery?(How can I stop queue animation jquery?)
  • 使用C#的井字游戏中的人工智能(Artificial Intelligence in Tic-Tac-Toe using C#)
  • 多少流量可以共享虚拟主机(对于Python Django站点)支持?(How Much Traffic Can Shared Web Hosting (for a Python Django site) support?)
  • 带有CIFilters的CAShapeLayer(CAShapeLayer with CIFilters)
  • 如何在Angular 2中读取JSON #text(How to read in Angular 2 the JSON #text)
  • 如何在xml中读取自闭标签的属性?(How to read self closing tag's attribute in xml?)
  • 无法使用http put将图像上传到亚马逊S3(Cannot upload image to amazon s3 using http put)
  • 文件结束无限循环(end of file infinite while-loop)
  • 在cpp的模板(template in cpp)
  • 在构建库时,clang和clang ++有什么区别?(What's the difference between clang and clang++ when building a library?)
  • ng类中的表达式(expression inside ng-class)
  • 在PHP中获取随机布尔值true / false(Get random boolean true/false in PHP)
  • 管道的高效分块用于严格的字节串(Efficient chunking of conduit for strict bytestring)
  • Python ternary_operator(如果其他标志做了其他操作,则执行其他操作)(Python ternary_operator (do-somthing if flag else do-another))
  • Sencha Touch面具发布(Sencha Touch mask ondisclosure)
  • 验证脚本上的通知[重复](Notices on validation script [duplicate])
  • 朋友功能(friend function)
  • 基于角坐标平移和变换平面几何(Translate and transform plane geometry based on corner coordinates)
  • Rails:'如果在本地运行'条件javascript标记包括(Rails: 'if running locally' conditional javascript tag include)
  • 解压文件(Unzipping files)
  • 使用ui-router以角度加载变量状态(loading in variable states with ui-router in angular)
  • 创建Azure云服务需要多长时间?(how long does it take to create an Azure Cloud Service? How to view log information?)
  • 指向整数的指针数组(Array of pointers to integers)
  • Laravel服务提供商没有看到我的包的主要类(Laravel service provider does not see the main class of my package)
  • 这个关于VSS / RSS / PSS / USS的解释是否准确?(Is this explanation about VSS/RSS/PSS/USS accurate?)
  • 在Django-Admin中通过row-id排序显示项目(Ordering the display items by row-id in Django-Admin)
  • 如何使用cythonize启用`--embed`?(How to enable `--embed` with cythonize?)
  • 用于将文本多行设置的Excel脚本(Excel script for ereasing text multiple rows)