C multiple types function

与世无争的帅哥 提交于 2019-12-12 16:14:21

问题


I'd like to write some functions in C but they have to be available for all numeric types (int, float, double). What is good practise? Use pointer on void (and pointer to function of course)? Or write a different function for every type?

For example:

 float func(float a, float b) {
   return a+b;
 }

回答1:


If you can use C11, _Generic can help:

#include <stdio.h>

int ifunc(int a, int b) { return a+b; }
float ffunc(float a, float b) { return a+b; }
double dfunc(double a, double b) { return a+b; }

#define func(x, y) \
   _Generic((x), int: ifunc, float: ffunc, double: dfunc, default: ifunc)(x, y)

int main(void)
{
    {
        int a = 1, b = 2, c;
        c = func(a, b);
        printf("%d\n", c);
    }
    {
        float a = .1f, b = .2f, c;
        c = func(a, b);
        printf("%f\n", c);
    }
    {
        double a = .1, b = .2, c;
        c = func(a, b);
        printf("%f\n", c);
    }
    return 0;
}



回答2:


As C does not have multiple dispatch (function overloading) like C++ (EDIT: unless you use C11, which has _Generic) , you have to name the functions for each type differently, like funcInt(int a, int b); funcFloat(float a, float b);

OR

use GCC style statement-expression macros which allow typeof() to kind of fake it.




回答3:


In C++, this would have easily been done with templates or function overloading. The only way I know in C is to write a different function for every type.

You can use a function taking two void* and compute with them, but it's extremely misleading for the user: what if there is a special type for which another version of the function is available but the user uses the void* function? This can lead to big problems, and is not recommended.

For a practical example of this, look at the standard string conversion functions atoi, atol, atof located in stdlib.h. One function per variable type.




回答4:


The old style C way is to use a union and a discriminator:

union multi_num {
    uint32_t  small_num;
    uint64_t  large_num;
    float     float_num;
};

struct multi_type {
    int discriminator;
    union multi_num val;
};

int
add_fun (struct multi_type var1, struct multi_type var2, struct multi_type *ret_val)
{

    if (var1.discriminator != var2.discriminator) {
        return -1;
    }
    ret_val->discriminator = var1.discriminator;
    switch (var1.discriminator) {
        case 1:
            ret_val->val.small_num = var1.val.small_num + var2.val.small_num;
            break;
        case 2:
            ret_val->val.large_num = var1.val.large_num + var2.val.large_num;
            break;
        case 3:
            ret_val->val.float_num = var1.val.float_num + var2.val.float_num;
            break;
    }

    return 0;
}

Then you can call it like this:

struct multi_type var1, var2, var3 = {0};

var1.discriminator = 1;
var2.discriminator = 1;

var1.val.small_num = 1;
var2.val.small_num = 12;
ret = add_fun(var1, var2, &var3);

if (0 == ret) {
    printf("add worked, ret is %d\n", var3.val.small_num);
} else {
    printf("add failed\n");
}


来源:https://stackoverflow.com/questions/34733044/c-multiple-types-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!