如何传递类型通用的函数指针?

时间:2019-04-07 19:20:36

标签: c

这是我的代码:

 #include <stdio.h>
 #include <tgmath.h>

 double complex execmathfunc(double complex val, double complex (*mathfunc)(double complex))
 {
     return mathfunc(val);
 }

 int main()
 {
     double complex val = -1;
     val = execmathfunc(val, sqrt); //if I put csqrt here it works
     printf("%.1f+%.1fi", creal(val), cimag(val));
     return 0;
 }

如果我使用csqrt,此代码将起作用,并且将按预期输出0.0+1.0i,但是如果我使用常规sqrt(将希望寄托于{{1 }}),它为实部输出一个垃圾值,为虚部输出0。将它们作为参数传递时,是否有任何方法可以解决?还是我需要坚持使用tgmath.h和所有其他复杂函数?

我相信代码的行为方式是这样的,因为tgmath函数是作为函数宏实现的,并且只有在名称后跟csqrt时它们才会扩展。

3 个答案:

答案 0 :(得分:1)

在C语言中没有类型通用的函数指针。

但是,您可能具有针对不同相关类型的指针结构,例如


typedef enum  { 
    USE_FLOAT = 0,
    USE_DOUBLE = 1, 
    // USE_LONG_DOUBLE = 2   // maybe you have this one as well
} complex_component_type_selector;

typedef struct {
    union {
        float complex (*float_)(float complex);
        double complex(*double_)(double complex);
    } function_ptr;
    complex_component_type_selector component_type;
} variant_function;

typedef union {
   union {
       float complex float_;
       double complex double_
   } datum;
   complex_component_type_selector component_type;
} variant_complex_datum;

您可以将variant_complex_functionvariant_complex_datum一起传递给您,以得到您想要的东西。

...现在,我的建议是对某些variants进行一些粗俗的评估。我敢肯定,有一些C语言的库,它们更加完善和全面……哦,是的,你去了:

Variant datatype library for C

答案 1 :(得分:0)

_Complex double不是doublesqrt占双倍,而csqrt占_Complex的两倍。 我没有检查实现,但我想说的是您传递的实际上是指向sqrt函数的指针而不是数字。

答案 2 :(得分:0)

  

我相信代码的行为是这样的,因为tgmath函数是作为函数宏实现的,并且只有在名称后跟()时,它们才会扩展。

  

有什么办法可以解决...?

没有直接的解决方法。

使用<tgmath.h>,代码无法提取将被某种类型的对象调用的函数。

您可以使用_Generic编写自己的函数集,但我认为您知道这一点,并且正在尝试避免使用它。