3

I'm trying to pass a class method to another class method using template, and cannot find any answer on how to do (no C++11, boost ok):

I simplified the core problem to :

class Numerical_Integrator : public Generic Integrator{
    template <class T>
    void integrate(void (T::*f)() ){
         // f(); //already without calling  f() i get error
    }
}

class Behavior{
    void toto(){};

    void evolution(){
        Numerical_Integrator my_integrator;
        my_integrator->integrate(this->toto};
}

I get as error:

error: no matching function for call to ‘Numerical_Integrator::integrate(<unresolved overloaded function type>)’this->toto);
note:   no known conversion for argument 1 from ‘<unresolved overloaded function type>’ to ‘void (Behavior::*)()’

Thank you.

Bonus: What about with arguments ?

class Numerical_Integrator{
    template <class T, class Args>
    double integrate(void (T::*f)(), double a, Args arg){
         f(a, arg);
    }
}

class Behavior{
    double toto(double a, Foo foo){ return something to do};

    void evolution(){
     Foo foo;
     Numerical_Integrator my_integrator;
     my_integrator->integrate(this->toto, 5, foo};
}
Quentin
  • 62,093
  • 7
  • 131
  • 191
Napseis
  • 833
  • 2
  • 10
  • 24
  • 2
    [Boost function](http://www.boost.org/doc/libs/1_61_0/doc/html/function.html) and [Boost bind](http://www.boost.org/doc/libs/1_61_0/libs/bind/doc/html/bind.html)? Or take a look at the [standard algorithm library](http://en.cppreference.com/w/cpp/algorithm) and see how they handle "predicates"? – Some programmer dude Jun 01 '16 at 12:12
  • What do you need the T for? Validation? – thorsan Jun 01 '16 at 12:16
  • `f(a, arg);`<- you need also the object that will act as `this` into the function. – coyotte508 Jun 01 '16 at 12:31
  • @ thorsan : i want to be able to give anything to the integrate(). @ coyotte508: ok, but the compiler complains even without calling f(), see the commented line in the first example. – Napseis Jun 01 '16 at 12:44

1 Answers1

8

Your question is not really about passing a class method as part of a template parameter.

Your question is really about correctly invoking a class method.

The following non-template equivalent will not work either:

class SomeClass {

public:

     void method();
};

class Numerical_Integrator : public Generic Integrator{
    void integrate(void (SomeClass::*f)() ){
         f();
    }
}

A class method is not a function, and it cannot be invoked as a function, by itself. A class method requires a class instance to be invoked, something along the lines of:

class Numerical_Integrator : public Generic Integrator{
    void integrate(SomeClass *instance, void (SomeClass::*f)() ){
         (instance->*f)();
    }
}

You need to revise the design of your templates, and/or class hierarchies in order to resolve this first. Once you correctly implement your class method invocation, implementing a template should not be an issue.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • Thanks for your answer. However using void integrate(SomeClass *instance, void (SomeClass::*f)() ) still give the same error: no known conversion for argument 2 from ‘’ to ‘void (Behavior::*)()’ – Napseis Jun 01 '16 at 12:41
  • 1
    The correct syntax for obtaining a pointer to a method is `&Class::method`. – Sam Varshavchik Jun 01 '16 at 12:51
  • fantastic, it compiles now. Where can i find explanations about this ? Thanks – Napseis Jun 01 '16 at 12:56