Hi I'm trying to create an array of function pointers contained within a class, the C++11 way. Can I have some help with this as I'm getting a bit mixed up. Here's what I have done so far. They are made up classes to define the problem.

#include <iostream>
#include <functional>
#include <vector>

using namespace std;

class CPerson;

class CAle
{
public:
    CAle(void) {};
    ~CAle(void) {};

    bool Sip1(CPerson* pPerson1, CPerson* pPerson2) { cout << "Sip 1" << endl; };
    bool Sip2(CPerson* pPerson1, CPerson* pPerson2) { cout << "Sip 2" << endl; };
    bool Sip3(CPerson* pPerson1, CPerson* pPerson2) { cout << "Sip 3" << endl; };
    bool Sip4(CPerson* pPerson1, CPerson* pPerson2) { cout << "Sip 4" << endl; };
    bool Sip5(CPerson* pPerson1, CPerson* pPerson2) { cout << "Sip 5" << endl; };
};

enum enSIPS
{
    enSip1 = 0,
    enSip2,
    enSip3,
    enSip4,
    enSip5,
    enSipCount
};

class CPerson
{
public:
    CPerson(void) {};
    ~CPerson(void) {};

    typedef std::function<bool(CPerson*, CPerson*)> FUNCTIONPOINTER;
    vector<FUNCTIONPOINTER> fp_Sip;
};

int main(void)
{
    CAle Ale;
    CPerson Person;

    Person.fp_Sip.push_back(mem_fn(&CAle::Sip1));
    Person.fp_Sip.push_back(mem_fn(&CAle::Sip2));
    Person.fp_Sip.push_back(mem_fn(&CAle::Sip3));
    Person.fp_Sip.push_back(mem_fn(&CAle::Sip4));
    Person.fp_Sip.push_back(mem_fn(&CAle::Sip5));

    CPerson* pP1, *pP2;
    for (auto it = Person.fp_Sip.begin(); it != Person.fp_Sip.end(); ++it)
        (*it)(pP1, pP2); // <== Error No instance of function

    Person.fp_Sip.at(enSip3)(pP1, pP2); // <== Error No instance of function

    cout << "End of program...!";
    cin.get();
    return 1;
};

Errors:
c:\program files (x86)\microsoft visual studio 11.0\vc\include\xrefwrap(462): error C2440: 'newline' : cannot convert from 'CPerson *' to 'CAle *'

and more

Recommended Answers

All 4 Replies

Are you sure you don't get any errors on the lines where you call push_back? Because that's where I would expect errors to happen.

Anyway the problem I see is that your functions are member functions of CAle and thus need to be called on an object of type CAle. By wrapping them with mem_fn you're creating a function object that takes three arguments: an object of type CAle on which to call the function and two CPerson pointers to pass as arguments. However your vector is supposed to store functions/function objects that take two arguments, not three, and the first argument is supposed to be of type CPersion*, not CAle.

I'm sorry I can't figure this out. I tried
auto fp_Sip = mem_fn(&CAle::Sip1);
Then call as fp_Sip(Ale, pP1, pP2);
But I cant specify auto within the class declaration. I need to use auto with mem_fn because I dont know who to declare the function with the right amount of parameters for both the function requirements and to satisfy mem_fn.

...Please can you show me an example...?

I'm not sure what you mean. If you want to put your member functions into your vector, you need to change the type of your vector (and then also change the calls when you call the functions). An example of this would be:

class CPerson
{
        public:
                CPerson(void) {};
                ~CPerson(void) {};
                typedef std::function<bool(CAle&, CPerson*, CPerson*)> FUNCTIONPOINTER;
                vector<FUNCTIONPOINTER> fp_Sip;
};

int main(void)
{
        // ...
        for (auto it = Person.fp_Sip.begin(); it != Person.fp_Sip.end(); ++it)
                (*it)(Ale, pP1, pP2);
        Person.fp_Sip.at(enSip3)(Ale, pP1, pP2);
}

If you don't want that, you need to bind the first argument using std::bind.

PS: Note that there's a lot of undefined behavior in your program as your bool functions don't actually return a value and you don't initialize your pointers.

PPS: The return value of main should be 0 - not 1 - when your application exits successfully.

Thanks for your reply.
Sorry about the lazyness of not returning values or not initialising the pointers. They are fixed as -
return true in Sip1..5
and
CPerson* pP1 = new CPerson also pP2

I missed the addition of the first argument in the declaration because I was hung up on looking at intellisence's red line on the caller. Which still hasn't gone - even though it compiles and runs perfectly.

Thanks and blessings to you.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.