Emulating std::bind in C

前端 未结 4 1754
北荒
北荒 2021-01-12 16:43

I\'m using std::bind to provide a callback while abstracting some logic by binding some parameters first. i.e.

void start() {

    int secret_id = 43534;

           


        
4条回答
  •  自闭症患者
    2021-01-12 17:30

    As 6502 explained, it is not possible to do this in portable C without some kind of context argument being passed to the callback, even if it doesn't name secret_id directly. However, there are libraries such as Bruno Haible's trampoline that enable creation of C functions with additional information (closures) through non-portable means. These libraries do their magic by invoking assembly or compiler extensions, but they are ported to many popular platforms; if they support architectures you care about, they work fine.

    Taken from the web, here is an example of code that trampoline enables is this higher-order function that takes parameters a, b, and c (analogous to your secret_id, and returns a function of exactly one parameter x that calculates a*x^2 + b*x + c:

    #include 
    
    static struct quadratic_saved_args {
        double a;
        double b;
        double c;
    } *quadratic_saved_args;
    
    static double quadratic_helper(double x) {
        double a, b, c;
        a = quadratic_saved_args->a;
        b = quadratic_saved_args->b;
        c = quadratic_saved_args->c;
        return a*x*x + b*x + c;
    }
    
    double (*quadratic(double a, double b, double c))(double) {
        struct quadratic_saved_args *args;
        args = malloc(sizeof(*args));
        args->a = a;
        args->b = b;
        args->c = c;
        return alloc_trampoline(quadratic_helper, &quadratic_saved_args, args);
    }
    
    int main() {
        double (*f)(double);
        f = quadratic(1, -79, 1601);
        printf("%g\n", f(42));
        free(trampoline_data(f));
        free_trampoline(f);
        return 0;
    }
    

提交回复
热议问题