Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace lambda function with polymorphic member function

I have the following member in a polymorphic class Parent and I am looking for a way to replace foo by some kind of virtual member bar:

void Parent::myFunc() {
    // lots of variables
    // complicated calculations

    while (/* loop condition */) {
        // more variables and calculations

        auto foo = [&](int n) {/* ... */};

        foo(42);
        // want to replace with virtual
        // bar(42);
    }
}

The problem I am having is that foo captures everything, and I do not know that correct way to grant bar the same access.

  1. Passing everything to bar as parameters would lead to a big parameter list, and does not seem to be an elegant solution
  2. I can also turn local variables of myFunc() into members of Parent, but this would needlessly extend the life times of those variables, especially for the loop variables.
like image 778
Yifan Lai Avatar asked Sep 21 '19 20:09

Yifan Lai


1 Answers

You’re right to not want to make the locals into members—which would, among other things, lose thread-compatibility. Since overriding functions can be defined in other translation units, you have to define some sort of interface and call it.

If you want to avoid a long parameter list, gang the arguments into a struct (which might be a protected member type of the base class). If appropriate, you can even reuse the struct object for each iteration and just update the relevant fields, or make them be references to the appropriate local variables.

You can also, if it works for your derived classes, define several virtual functions to be called with subsets of your currently-captured variables.

In either case, these emulations of capturing would be called from within the real lambda used for whatever purpose (e.g., a callback as mentioned in the comments).

like image 159
Davis Herring Avatar answered Oct 12 '22 08:10

Davis Herring