简体   繁体   中英

How to use a C++ lambda to convert a member function pointer to a normal function pointer for use as a callback

I have some code that needs a C function, but I want to instantiate a bunch of class instances and pass a member function from that class as the C function. I need to capture N instances concurrently. I'm hoping I can do it as a lambda.

Here's what the resulting function should look like (roughly):

// This is the code I want to interface with:

typedef void func(ParamClass param); // ParamClass is NOT my class

extern void notMyCode1(func funcArg); // Code I want to call, saves funcArg
extern void notMyCode2()  // uses saved funcArgs


// Here is the type of class I want to instantiate:

class MyClass {
   public:
       MyClass(int arg) : saveArg(arg) {}

       int saveArg;

   void myFunc(ParamClass param) {
       // uses saveArg and param to do the right action
   }

};

void useCase(void) {
   for (int i = 0; i < max; ++i) {
       MyClass myInstance(Myclass(i)); // maybe need vector to hold these?
       notMyCode1(myInstance.myFunc); // this code is what I don't know how to write
    }
    notMyCode2();
}

Background. The library I want to call is Google Benchmark. notMyCode1 is their benchmark registration function. notMyCode2 runs the benchmarks that were registered. ParamClass is data their code passes into the benchmark.

Now, normally, one passes a simple C function to the registration code, one for each benchmark one wishes to run. However, I want to run the same code over and over again parameterizing it by this number "i" and have each "i" treated as a separate benchmark. So, I want to capture "i" in a class (or via a lambda, but something that yields me multiple C function pointers with the value of "i" bound in each one). I tried making "i" a parameter to the benchmark and passing it in, but then the benchmark code treated "i" as something to sum over (and I want each "i" treated as a unique benchmark with a different parameter for the statistics to be calculated over).

This seems like something that ought to be simple to do, (it's just a closure) but I'm not that conversant with function pointers (or C++ lambdas). If it were my code, I would just pass the class instance in, but it isn't.

I've seen examples that use static functions in the class, but I specifically want to capture the value of "i" and get multiple function pointers, each one capturing a different value of "i".

You cannot.

A lambda only has a conversion to function pointer if it is stateless (ie there's no captures). To call a member function from a lambda, you need a pointer to an object with which to call the member function. This is captured, rendering the lambda object not convertible to a simple function pointer.

The only option you might have is to do the index parametrization at compile time using templates. Then you return to using simple static functions of a class template which can be passed as a C callback.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM