有没有办法在C中实现函数重载?我正在寻找简单的函数被重载像
foo (int a)
foo (char b)
foo (float c , int d)
我认为没有直接的方法;我在寻找变通办法,如果有的话。
有没有办法在C中实现函数重载?我正在寻找简单的函数被重载像
foo (int a)
foo (char b)
foo (float c , int d)
我认为没有直接的方法;我在寻找变通办法,如果有的话。
当前回答
如果你的编译器支持,试着将这些函数声明为extern " c++ ", http://msdn.microsoft.com/en-us/library/s6y4zxec(VS.80).aspx
其他回答
如前所述,c不支持重载。解决这个问题的常用方法是让函数接受带标签的联合。这是通过一个struct形参实现的,其中struct本身由某种类型指示符(例如枚举)和不同类型值的并集组成。例子:
#include <stdio.h>
typedef enum {
T_INT,
T_FLOAT,
T_CHAR,
} my_type;
typedef struct {
my_type type;
union {
int a;
float b;
char c;
} my_union;
} my_struct;
void set_overload (my_struct *whatever)
{
switch (whatever->type)
{
case T_INT:
whatever->my_union.a = 1;
break;
case T_FLOAT:
whatever->my_union.b = 2.0;
break;
case T_CHAR:
whatever->my_union.c = '3';
}
}
void printf_overload (my_struct *whatever) {
switch (whatever->type)
{
case T_INT:
printf("%d\n", whatever->my_union.a);
break;
case T_FLOAT:
printf("%f\n", whatever->my_union.b);
break;
case T_CHAR:
printf("%c\n", whatever->my_union.c);
break;
}
}
int main (int argc, char* argv[])
{
my_struct s;
s.type=T_INT;
set_overload(&s);
printf_overload(&s);
s.type=T_FLOAT;
set_overload(&s);
printf_overload(&s);
s.type=T_CHAR;
set_overload(&s);
printf_overload(&s);
}
通常在名称前附加或加一个表示类型的疣子。在某些实例中,可以不使用宏,但这取决于您要做什么。C中没有多态性,只有强制。
简单的泛型操作可以用宏完成:
#define max(x,y) ((x)>(y)?(x):(y))
如果你的编译器支持typeof,更复杂的操作可以放在宏中。然后可以使用符号foo(x)来支持不同类型的相同操作,但不能在不同重载之间改变行为。如果需要实际的函数而不是宏,则可以将类型粘贴到名称上,然后使用第二次粘贴来访问它(我还没有尝试过)。
就你的意思来说——不,你不能。
你可以像这样声明一个va_arg函数
Void my_func(char*格式,…);
,但是您需要在第一个参数中传递一些关于变量数量及其类型的信息-就像printf()所做的那样。
下面是我发现的演示C语言中函数重载的最清晰、最简洁的例子:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int addi(int a, int b) {
return a + b;
}
char *adds(char *a, char *b) {
char *res = malloc(strlen(a) + strlen(b) + 1);
strcpy(res, a);
strcat(res, b);
return res;
}
#define add(a, b) _Generic(a, int: addi, char*: adds)(a, b)
int main(void) {
int a = 1, b = 2;
printf("%d\n", add(a, b)); // 3
char *c = "hello ", *d = "world";
printf("%s\n", add(c, d)); // hello world
return 0;
}
https://gist.github.com/barosl/e0af4a92b2b8cabd05a7
如果你的编译器是gcc的,并且你不介意每次添加新的重载时进行手动更新,你可以做一些宏魔术,并在调用方方面得到你想要的结果。但这是有可能的
看一下__builtin_types_compatible_p,然后用它定义一个宏,做类似的事情
#define foo(a) \
((__builtin_types_compatible_p(int, a)?foo(a):(__builtin_types_compatible_p(float, a)?foo(a):)
但是很讨厌,就是不要
编辑:C1X将获得对类型泛型表达式的支持,它们看起来像这样:
#define cbrt(X) _Generic((X), long double: cbrtl, \
default: cbrt, \
float: cbrtf)(X)