用void重载函数

时间:2019-05-28 03:32:13

标签: c

尝试使用_Generic重载C编程语言中的函数。找到了例子:

这个例子:

#include <stdio.h>
#include <math.h>

void display_float(float dispid) ;
void display_int(int dispid) ;
void display_void(void) ;

#define display(x) _Generic((x), \
          float: display_float, \
          int: display_int,  \
          default: display_float  \
)(x)

void display_void(void){
    printf("display id: 0\n") ;
}

void display_float(float dispid){
   printf("display id: %f\n", dispid) ;
}

void display_int(int dispid){
    printf("display id: %d\n", dispid) ;
}

void main(void){

    display(5) ;
    display(6.5) ;
}

现在我也想用display()重载该函数。意味着该函数将接收void,调用函数display_void(),并显示0。似乎无法做到这一点。任何帮助将不胜感激。

编辑1:

另外,请参见示例here。我认为,其中一个示例是传递指向void的指针。可以实现吗?

2 个答案:

答案 0 :(得分:4)

好的。 Overload Macro on Number of Arguments

void display_float(float dispid) ;
void display_int(int dispid) ;
void display_void(void) ;

#define _display_1(x) _Generic((x), \
          float: display_float, \
          int: display_int,  \
          default: display_float  \
)(x)
#define _display_0()  display_void()
#define _display_N(_0,_1,N,...)  _display_ ## N
#define display(...) _display_N(_0,##__VA_ARGS__,1,0)(__VA_ARGS__)

int main() {
    display();
    display(1);
    display(1.1);
}

godbolt上进行了测试。

请注意,, ##__VA_ARGS__是C标准中未描述的gcc extension

答案 1 :(得分:1)

  

尝试重载C编程语言中的函数

C11没有任何function overloading ,而 _Genericgenericity 的代表,没有< / em>是否超载,请通过阅读n1570进行检查。考虑切换到提供函数重载的C ++(或什至更好的Rust)。请注意,对C函数使用void(不是void*,而只是void)参数是非法的,因此C中没有任何"top"超类型,这将是其他类型的超类型(并且由于calling conventionsABI的考虑,使得C成为低级编程语言,有时甚至称为“ {{3 }}汇编程序”)。请阅读有关portableabstract interpretation的更多信息。

如果_Generic是用于重载,则C11标准委员会的成员-所有编程语言专家和足够好的英语作者-都应将其命名为_Overload,但他们明智地没有这么做。

深思熟虑(假设stderrstdin都像您希望它们正常工作一样)
假设的display(stderr)display(*stdin)display("abc")呢?

(以下错误建议,后面有更好的建议)

不好的方法

这不起作用!

您的display_void应该接受一些争论,例如

void display_void(void*p) { printf("p@%p\n", p);

那么您可能会有:

#define display_anything(P) display_void((void*)(&(P)))

使用

#define display(x) _Generic((x), \
      float: display_float, \
      int: display_int,  \
      default: display_anything  \
)(x)

更好的建议

由于这行不通(而且行不通),因此以其他方式设计代码。例如,考虑使用一些type systems,例如tagged union。从Glib的here实现中获取灵感。