-1

I am writing a code to store function pointers in a vector of function pointers. But in my implementation, the function that I am going to store in a vector is a member function of a class that is stored in another std::map as a pointer. Below is the code snippet.

class img_preprocess(){ 
public:
   std::vector<void(*)(int)> receivers;
}

class detector(){
public:
   void push(int val) {
      //some code here
   }


class tracker(){
private:
   std::map< int, img_preprocess* > img_actors;
   std::map< int, detector* > detect_actors;

public:
   tracker(){
      this->img_actors.insert({ 1, new img_preprocess() });
      this->detect_actors.insert({ 1, new detector() });

      // adding the detector::push function to img_preprocess receivers vector
      this->img_actors[1]->receivers.push_back(
          & ( this->detect_actors[1]->push )       // this line gives me the error
      )
   }
}

My intention is to keep a function pointer for the push function of the detector object inside of the img_preprocess object's receivers vector. The above approach gives me the a pointer to a bound function may only be used to call the function error. Any ideas on how to overcome this error and accomplish my intention?

EDIT 01:

In my case I have to store several push functions inside of the receivers vector. Those push functions are members of classes like detector( ex: matcher::push, distributor::push)

class Matcher{
public:
   void push(int val){
      //some code here
   }
}

class Distributor{
public:
   void push(int val){
      //some code here
   }
}
bawwa
  • 1
  • 2
  • Loosely related, you could be interested in [type erasure](https://www.youtube.com/watch?v=tbUCHifyT24). – Enlico Mar 05 '21 at 07:50
  • pointer to member functions are very different. There are already lots of duplicates on that. Either make the function static if it doesn't need to access object data, or you must have and object attached to it – phuclv Mar 05 '21 at 08:03

2 Answers2

0

use std::function. Read more about here

axiiom
  • 1
  • 1
0

Class definitions in C++ should not be like this: class img_preprocess(). The preceding () will trigger a syntax error. Non-inheriting, non-templated class definitions typically follow this format.

class ClassName 
{
    /* Class members go here. */
};

When dealing with member function pointer, the vector's value_type should be the member function type. In your case the member function type is void (detector::*)(int).

typedef void (detector::*FuncT)(int);

class img_preprocess { 
public:
   std::vector<FuncT> receivers;
}

And when adding the member function pointer, you cannot add it to the vector using the object instance. You must use the :: operator.

this->img_actors[1]->receivers.push_back(&(detector::push));

Now when calling,

(this->detect_actors[1]->(*this->img_actors[1]->receivers[/* whatever the index */]))(/* whatever the argument */);

Now put everything together and your final code will look like this.

class detector; // Forward declaration needed for the typedef and img_preprocess object.
typedef void(detector::* FuncT)(int);

class img_preprocess {
public:
    std::vector<FuncT> receivers;
};

class detector {
public:
    void push(int val) {
        //some code here
    }
};


class tracker {
private:
    std::map< int, img_preprocess* > img_actors;
    std::map< int, detector* > detect_actors;

public:
    tracker() {
        this->img_actors.insert({ 1, new img_preprocess() });
        this->detect_actors.insert({ 1, new detector() });

        // adding the detector::push function to img_preprocess receivers vector
        this->img_actors[1]->receivers.push_back(&(detector::push));
    }
};

Edit: If you want to store member function pointers of other objects, apart from detactor's, you can use std::function and std::bind to add member function pointers to the vector,

#include <functional>    // For std::function and std::bind

class img_preprocess {
public:
    std::vector<std::function<void(int)>> receivers;
};

...
this->img_actors[1]->receivers.push_back(std::bind(&detector::push, this->detect_actors[1], std::placeholders::_1));    // Adding the function pointer to the vector.
this->img_actors[1]->receivers[0](5);    // When calling the function.

Additional: Using generic std::function objects with member functions in one class

D-RAJ
  • 3,263
  • 2
  • 6
  • 24
  • Thank you so much for the descriptive explanation. But in my case, I need to store several push functions inside of the receivers vector. Those push functions are from different classes like detector(ex: matcher::push, distributor::push). Any idea or suggestion on how to achieve it? – bawwa Mar 05 '21 at 06:37
  • Rather than `std::bind` you can use a lambda expression: `[this](int val}{ detect_actors[1].push(val); }` – Caleth Mar 05 '21 at 09:14
  • 1
    Thank you so much @D-RAJ Your method worked for me. – bawwa Apr 21 '21 at 11:20