有没有办法在C中实现函数重载?我正在寻找简单的函数被重载像
foo (int a)
foo (char b)
foo (float c , int d)
我认为没有直接的方法;我在寻找变通办法,如果有的话。
有没有办法在C中实现函数重载?我正在寻找简单的函数被重载像
foo (int a)
foo (char b)
foo (float c , int d)
我认为没有直接的方法;我在寻找变通办法,如果有的话。
当前回答
如果你的编译器是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)
其他回答
有以下几种可能性:
Printf样式函数(类型作为参数) Opengl风格函数(输入函数名) c++的c子集(如果你能使用c++编译器)
下面的方法类似于a2800276,但添加了一些C99宏魔术:
// we need `size_t`
#include <stddef.h>
// argument types to accept
enum sum_arg_types { SUM_LONG, SUM_ULONG, SUM_DOUBLE };
// a structure to hold an argument
struct sum_arg
{
enum sum_arg_types type;
union
{
long as_long;
unsigned long as_ulong;
double as_double;
} value;
};
// determine an array's size
#define count(ARRAY) ((sizeof (ARRAY))/(sizeof *(ARRAY)))
// this is how our function will be called
#define sum(...) _sum(count(sum_args(__VA_ARGS__)), sum_args(__VA_ARGS__))
// create an array of `struct sum_arg`
#define sum_args(...) ((struct sum_arg []){ __VA_ARGS__ })
// create initializers for the arguments
#define sum_long(VALUE) { SUM_LONG, { .as_long = (VALUE) } }
#define sum_ulong(VALUE) { SUM_ULONG, { .as_ulong = (VALUE) } }
#define sum_double(VALUE) { SUM_DOUBLE, { .as_double = (VALUE) } }
// our polymorphic function
long double _sum(size_t count, struct sum_arg * args)
{
long double value = 0;
for(size_t i = 0; i < count; ++i)
{
switch(args[i].type)
{
case SUM_LONG:
value += args[i].value.as_long;
break;
case SUM_ULONG:
value += args[i].value.as_ulong;
break;
case SUM_DOUBLE:
value += args[i].value.as_double;
break;
}
}
return value;
}
// let's see if it works
#include <stdio.h>
int main()
{
unsigned long foo = -1;
long double value = sum(sum_long(42), sum_ulong(foo), sum_double(1e10));
printf("%Le\n", value);
return 0;
}
如果你的编译器是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)
下面是我发现的演示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
这可能没有任何帮助,但如果你使用clang,你可以使用overloadable属性-即使在编译为C时也可以
http://clang.llvm.org/docs/AttributeReference.html#overloadable
头
extern void DecodeImageNow(CGImageRef image, CGContextRef usingContext) __attribute__((overloadable));
extern void DecodeImageNow(CGImageRef image) __attribute__((overloadable));
实现
void __attribute__((overloadable)) DecodeImageNow(CGImageRef image, CGContextRef usingContext { ... }
void __attribute__((overloadable)) DecodeImageNow(CGImageRef image) { ... }