mab*_*enk 0 c overloading variadic-functions
我正在寻找一种优雅的方法来避免重写函数,其实现几乎相同,但只有签名(输入参数的数量和它们的数据类型)是不同的.我知道在C中不可能进行函数重载.我也知道可变函数的存在.但我认为他们在这种情况下不会有所帮助.
考虑以下问题,我们需要计算三角形的面积.我们有两个函数实现两个不同的公式:S = 1/2bh和S = sqrt(s(sa)(sb)(sc)).除了计算区域外,每个函数还修改参数nb或nthr.最后,有一个顶级例程bisect_area_...,它在给定函数上启动二分程序area_tria1或area_tria2为参数nb或函数优化它nthr.目前我明确地实现了两个二分函数:一个用于签名,area_tria1另一个用于签名area_tria2.我觉得必须有更好,更优雅的方式,才能拥有一个通用的二分函数bisect_area_tria().请注意,在实际情况中,我手边的输入参数数据类型也不同.
下面是函数签名的骨架伪代码:
// Calculate area of triangle, modify and return parameter 'nb'
void area_tria1_nb(..., int *nb, double b, double h, double *S) {
// change parameter 'nb'
...
S = 0.5*b*h;
}
// Calculate area of triangle, modify and return parameter 'nthr'
void area_tria1_nthr(..., int *nthr, double b, double h, double *S) {
// change parameter 'nthr'
...
S = 0.5*b*h;
}
// Optimise calculation of area of triangle, for parameter 'nb' or 'nthr'
void bisect_area_tria1(..., double b, double h, double *S, int (*area_tria1)(double, double)) {
}
// Calculate area of triangle, modify and return parameter 'nb'
void area_tria2_nb(..., int *nb, double a, double b, double c, double *S) {
// change parameter 'nb'
...
S = sqrt(s*(s-a)*(s-b)*(s-c));
}
// Calculate area of triangle, modify and return parameter 'nthr'
void area_tria_2_nthr(..., int *nthr, double a, double b, double c, double *S) {
// change parameter 'nthr'
...
S = sqrt(s*(s-a)*(s-b)*(s-c));
}
// Optimise calculation of area of triangle, for parameter 'nb' or 'nthr'
void bisect_area_tria2(..., double a, double b, double c, double *S, int (*area_tria2)(double, double, double)) {
}
void main() {
bisect_area_tria1(..., &nb, b, h, &S, area_tria1_nb);
bisect_area_tria1(..., &nthr, b, h, &S, area_tria1_nthr);
bisect_area_tria2(..., &nb, a, b, c, &S, area_tria2_nb);
bisect_area_tria2(..., &nthr, a, b, c, &S, area_tria2_nthr);
}
Run Code Online (Sandbox Code Playgroud)
天真,简单的方法:
#include <stdio.h>
void func_int (int x) { printf("%d\n", x); }
void func_char (char ch) { printf("%c\n", ch); }
#define func(param) \
_Generic((param), \
int: func_int(param), \
char: func_char(param)); \
int main()
{
func(1);
func((char){'A'});
}
Run Code Online (Sandbox Code Playgroud)
这是类型安全的,但只支持一个参数.一眼看上去似乎不够.
如果你想要完全可变的参数列表,那么你必须实现一种解析可变参数宏的方法__VA_ARGS__.可能,这是可能的.可能它很难看.可能,这不是你需要的.
通常,对函数重载的需求可能是"XY问题".您需要具有不同参数集的函数,并且您确信函数重载是解决它的最佳方法.因此,你问如何在C中进行函数重载.事实证明,这不一定是最好的方法.
更好的方法是使用单个struct参数创建一个函数接口,该参数可以适用于包含所有必需的参数.有了这样的界面,您可以使用上面的简单方法_Generic.类型安全且可维护.
| 归档时间: |
|
| 查看次数: |
628 次 |
| 最近记录: |