How to achieve function overloading in C?

前端 未结 14 2283
清歌不尽
清歌不尽 2020-11-22 03:16

Is there any way to achieve function overloading in C? I am looking at simple functions to be overloaded like

foo (int a)  
foo (char b)  
foo (float c , i         


        
相关标签:
14条回答
  • 2020-11-22 04:12

    Normally a wart to indicate the type is appended or prepended to the name. You can get away with macros is some instances, but it rather depends what you're trying to do. There's no polymorphism in C, only coercion.

    Simple generic operations can be done with macros:

    #define max(x,y) ((x)>(y)?(x):(y))
    

    If your compiler supports typeof, more complicated operations can be put in the macro. You can then have the symbol foo(x) to support the same operation different types, but you can't vary the behaviour between different overloads. If you want actual functions rather than macros, you might be able to paste the type to the name and use a second pasting to access it (I haven't tried).

    0 讨论(0)
  • 2020-11-22 04:13

    Can't you just use C++ and not use all other C++ features except this one?

    If still no just strict C then I would recommend variadic functions instead.

    0 讨论(0)
  • 2020-11-22 04:15

    The following approach is similar to a2800276's, but with some C99 macro magic added:

    // 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;
    }
    
    0 讨论(0)
  • 2020-11-22 04:15

    This may not help at all, but if you're using clang you can use the overloadable attribute - This works even when compiling as C

    http://clang.llvm.org/docs/AttributeReference.html#overloadable

    Header

    extern void DecodeImageNow(CGImageRef image, CGContextRef usingContext) __attribute__((overloadable));
    extern void DecodeImageNow(CGImageRef image) __attribute__((overloadable));
    

    Implementation

    void __attribute__((overloadable)) DecodeImageNow(CGImageRef image, CGContextRef usingContext { ... }
    void __attribute__((overloadable)) DecodeImageNow(CGImageRef image) { ... }
    
    0 讨论(0)
  • 2020-11-22 04:16

    Try to declare these functions as extern "C++" if your compiler supports this, http://msdn.microsoft.com/en-us/library/s6y4zxec(VS.80).aspx

    0 讨论(0)
  • 2020-11-22 04:19

    There are few possibilities:

    1. printf style functions (type as an argument)
    2. opengl style functions (type in function name)
    3. c subset of c++ (if You can use a c++ compiler)
    0 讨论(0)
提交回复
热议问题