Passing void from other class


#1

I’m trying to create a grid class which accept an integer and a void function from another class as arguments, but I’m stuck cause I’m not able to pass the void function.

Here some code

 void ofApp::draw(){
   grid.draw(12, bar.draw);
 }

Where grid refers to

   void GrigliataClass::draw(int grid, void (* element)()){
    int cell = ofGetHeight() / grid;
    int offset = cell / 2;
    for (unsigned int i = 0; i < grid; i++) {
      int x = i * cell + offset;
      for (unsigned j = 0; j < grid; j++) {
        int y = j * cell + offset;
        ofPushMatrix();
        ofTranslate(x, y);
        element();
        ofPopMatrix();
      }
    }
  }

And bar.draw points to

   void BarrettaClass::draw(){
      ofDrawCircle(0, 0, 8);
   }

The error i get is this
Cannot initialize a parameter of type 'void (*)()' with an rvalue of type 'void'
any ideas?


#2

you can’t pass a member function like that you need to convert it into a function with an argument where the first argument is the object to act upon since member functions don’t belong to the object but to the class

in any case it’s easier to use std::function as in:

void draw(int grid, std::function<void()> element)

and then call as:

grid.draw(12, std::bind(&BarrettaClass::draw, a, std::placeholders::_1));

or even easier:

grid.draw(12, [&]{a.draw()});

where you create a lambda that calls the object capturing it by reference

I’d say though that it’s kind of a weird design and something like:

template<typename Draw>
void draw(int grid, Draw & element){
    int cell = ofGetHeight() / grid;
    int offset = cell / 2;
    for (unsigned int i = 0; i < grid; i++) {
      int x = i * cell + offset;
      for (unsigned j = 0; j < grid; j++) {
        int y = j * cell + offset;
        ofPushMatrix();
        ofTranslate(x, y);
        element.draw();
        ofPopMatrix();
      }
    }
  }

then call it as:

grid.draw(12, a);

doesn’t require function pointers. you need to put the implementation of that function in the .h though since it’s a template


#3

There is a good tutorial about lambdas in c++, as @arturo with grid.draw(12, [&]{a.draw()}); was suggesting.
https://openframeworks.cc/ofBook/chapters/c++11.html#lambdafunctions


#5

Thanks, this is quite a lot to process, I’m gonna try this asap and let you know