Question

Here are the requirements posed by my application. I have a class A, that accepts a function pointer say cFunc, Basically in my implementation of A, I have it call cFunc multiple times.

The cFunc pointer itself should point to different functions depending upon the application. Thus for each application I create a class with the same function definition as cFunc, however I cannot assign the class's member function to this pointer

class A {
    typedef double (*Def_CFunc)(std::vector<double>);
    A(Def_CFunc _cFunc) { // Some implementation}
    // Other Functions
};

class B { double someFunc(std::vector<double> b); };
class C { double someOtherFunc(std::vector<double> a); };

int main () {
    B firstObj;
    C secondObj;

    // Depending upon the situation, I want to select class B or C
    double (*funcPointer)(std::vector<double>) = firstObj.someFunc; // Error in this line of code

    A finalObj(funcPointer);
}

So how do I make it such that any class with a member function of the given format can be used to initialize the class A?

Était-ce utile?

La solution

I'm not sure what exactly your requirements are, but it looks like you want an interface (or abstract base class in C++ lingo).

If both B and C inherit from a common base class, you can pass a pointer to this base class and invoke functions on it:

class I { virtual double func(std::vector<double> a) = 0; }
class B : public I { double func(std::vector<double> a); };
class C : public I { double func(std::vector<double> a); };

You can pass an I* pointer to A and just use i->func.

Autres conseils

Pointer to member function has different syntax than pointer to ordinary function and can only point to a method of one given class. To be able to point to methods in different classes use boost::function or if C++11 is available use std::function. These can hold any method or function of a given signature.

What you need is std::function together with either std::bind or lambda expressions (or the Boost equivalent of the first two), because member function pointers don't allow you to do that.

You can do it using std::bind + std::function. Lets write some template class wrapper, that takes any static type as input. Then use this wrapper in free function switch_obj. Usage is very simple.

typedef std::function<double(std::vector<double>)> my_foo;

template<class C>
struct switcher
{
    static my_foo convert(C* obj)
    {
        return my_foo( std::bind(&C::someFunc,obj,std::placeholders::_1) );
    }
};

template<class T>
my_foo switch_obj(T* obj)
{
    return switcher<T>::convert(obj);
}

void main()
{
    B firstObj;
    C secondObj;

    auto f =  switch_obj(&firstObj);
    A a(f);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top