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?

有帮助吗?

解决方案

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.

其他提示

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);
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top