4

My question is similar to this. And 'Karrek SB's answer actually helped me somewhat. I have these classes:

Base.h:

class Base{
public:
   Base(){}
   virtual ~Base(){}
   virtual void init() = 0;
};

A1.h:

#include <iostream>
#include "Base.h"

using namespace std;

class A1 : public Base{
public:
   A1(){}
   virtual ~A1(){};
   virtual void init(){
      cout << "A1::init() called" << endl;
   }
   void f1(){
      cout << "Im in A1::f1" << endl;
   }

   void f2(int val){
      cout << "Im in A1::f2 with val: " << val << endl;
   }
};

I have another class that should be able to store any generic member function with any type and number of args. The class looks something like this:

MFholder.h:

#include <functional>
#include <deque>

using namespace std;

class MFHolder{
    public:
       MFHolder(){};
       ~MFHolder(){};

       template<typename T, typename R, typename ... Args>
       R addMF(T & obj, R (T::*pf)(Args ...), Args&& ... args){
           mfp.push_back(function<void()>(bind(pf, &obj, forward<Args>(args) ...)));
       }

       void runTasks(){
           while(!mfp.empty()){
               auto task = mfp.front();
               mfp.pop_front();
               task();
           }
       }
    private:
       deque< function<void()> > mfp;
};

Now i want to add some member function to the MFHolder from main like this: main.cpp:

#include "A1.h"
#include "MFHolder.h"

int main(){
   MFHolder mfh;
   A1 a1Obj;
   //A2 a2Obj; //this should also work

   int val = 42;
   //mfh.addMF(a1Obj, &A1::f1); //this should also work
   mfh.addMF(a1Obj, &A1::f2, val);
   //add some more function calls here...


   //run all the tasks
   mfh.runTasks();

   return 0;
}

I get the following error when compiling my code.

no matching function for call to 'MFHolder::addMF(A1&, void (A1::*)(int), int&)'

And candidate is:

template<class T, class R, class ... Args> R MFHolder::addMF(T&, R (T::*)(Args ...), Args&& ...)

Thx in advance! :)

Community
  • 1
  • 1
hfm
  • 567
  • 2
  • 7
  • 24
  • As a quick workaround, you could try `mfh.addMFC(a1Obj, &A1::f2, static_cast(val));`. Otherwise, you could also get rid of the forwarding semantics and always have, say, const-references. – Kerrek SB Mar 18 '13 at 17:57
  • Can you change it to accept std::function instead, or are you just trying to avoid making the user type the call to bind? – metal Mar 18 '13 at 18:07
  • @KerrekSB, now I get "error: no matching function for call to 'MFHolder::addMF(A1&, void (A1::*)(int), const int&)'". – hfm Mar 18 '13 at 18:09
  • @metal, I am using std::function, std::bind and std::forward in my actual code. Just wanted to simplify the code here. – hfm Mar 18 '13 at 18:11
  • Right, I saw that, but can you just say `R addMF( const std::function& )`? (And why have it return R if you discarding the return type with the function anyway? Are you saying the code above works fine if you don't put it in the header file? – metal Mar 18 '13 at 18:16
  • 1
    You're right. Try `static_cast(val)` instead. – Kerrek SB Mar 18 '13 at 18:17
  • The "static_cast(val)" helped. Thx alot Kerrek SB. – hfm Mar 19 '13 at 10:57

1 Answers1

1

Either change Args&& to Args& in the definition of addMF or change val to move(val) when you invoke it.

dspeyer
  • 2,904
  • 1
  • 18
  • 24