0

I have an array of pointer-to-member functions in class A and need to access the elements in class B. My problem is either always getting a 1 returned when trying to access an array element or types not matching with each other.

What I've got so far is:

A.h:

#include <vector>

class A {

public:
    typedef void(*func_ptr)(void);

    A();

    void func1();
    void func2();
    void func3();

    std::vector<void(A::*)()> aFuncs;

private:
    void appendFunc(void(A::*function)());

};

A.cpp

#include "A.h"

void A::func1 {...}
void A::func2 {...}
void A::func3 {...}

void A::appendFunc(void(A::*function)()) {
    aFuncs.push_back(function);
}

A::A() {
    appendFunc(&A::func1);
    appendFunc(&A::func2);
    appendFunc(&A::func3);
}

B.h

#include "A.h"

class B {

    A a;

    void test(int value);

};

B.cpp

#include "B.h"

void B::test(int value) {
    // here i need to access the elements of the array aFuncs, so that i can 
    // call the functions of A
    // something like
    a.aFuncs[value];
}

The problem here e.g. is, that a.aFuncs[value] always returns 1 if I use it like this.

The only thing that worked for me so far is:

void B::test(int value) {
    typedef void (a::*fn)();

    fn funcPtr = &a::func1;

    (a.*funcPtr)();
}

But that solution is not using the array so not really helpful right now. Can someone help me with this problem? Is there something fundamental im not understanding?

0

3 Answers 3

2

You need to use a twice in order to call the function. Once to access the vector and then again to call the function. That monstrosity looks like

void B::test(int value) {
    (a.*a.aFuncs[value])();
}

To make it cleaner you can copy the function pointer into a variable and then use that function pointer to call the function. That would look like

void B::test(int value) {
    auto func = a.aFuncs[value];
    (a.*func)();
}

And you can see it working at this Live Example.

Sign up to request clarification or add additional context in comments.

1 Comment

thanks a lot, that worked like a charm and thanks for the explanation as well, as a newbie pointer-to-member functions are really a hard topic to wrap your head around :P
0

(a.*aFuncs[value])() works if aFuncs is global. In your example you should be able to do (a.*a.aFuncs[value])().

#include <iostream>
#include <array>
struct Foo {
    int one()   { std::cout << "one\n"; return 1; }
    int two()   { std::cout << "two\n"; return 2; }
    int three() { std::cout << "three\n"; return 3; }
};
std::array<int(Foo::*)(), 3> a = {{
    &Foo::one,
    &Foo::two,
    &Foo::three,
}};
int main() {
    Foo f;
    std::cout << "1: " << (f.*a[0])() << "\n";
    std::cout << "2: " << (f.*a[1])() << "\n";
    std::cout << "3: " << (f.*a[2])() << "\n";
}

Output:

one
1: 1
two
2: 2
three
3: 3

https://ideone.com/dd5TWP

1 Comment

thanks as well :) it worked and also gave me good insight on the topic
0

You can also use an alternative method by leveraging std::function if your compiler supports it:

std::array<std::function<void(Foo&)>, 3> a = {
    &Foo::one,
    &Foo::two,
    &Foo::three
};

and then calling with:

foo.a[0](foo);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.