Using member function pointers inside a class

Hi, I am trying to implement member function pointers in a class. I tried to work it out in a project and got plenty of errors. Now, I have written this small class and I see no error in my IDE. Do you see any error in there, I mainly copied what I have seen online, which is a shame because I do not really understand what I am doing. It seems weird that I have to call (this) when invoking the fct, it is very different from a normal fct ptr. I am also concerned about my private function that takes a member fct ptr as an argument and set it to the private member pointer. What are your comments? thanks!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class foo
{
private:
    void (foo::*_memberFctPtr)(bool);
    void _bar(bool running) {}
    void _setFct( void (foo::*setFct)(bool) ) {_memberFctPtr = setFct; }

public:
    foo(/* args */) {
        _memberFctPtr = &foo::_bar;  
    }
    ~foo() {}
    void goToBar() { _setFct(foo::_bar); }  //I get no error here but I get invalid use of non static member function from the argument of _setFct() in my other project

    void run() { (this->*_memberFctPtr)(true); }
    
};
Last edited on
Aren't you just missing the ampersand in front of foo::bar?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>

class foo
{
private:
    void (foo::*_memberFctPtr)(bool);
    void _bar(bool) { std::cout << "barbarbar\n"; }
    void _baz(bool) { std::cout << "bazbazbaz\n"; }
    void _setFct( void (foo::*setFct)(bool) ) {_memberFctPtr = setFct; }
public:
    foo() { _memberFctPtr = &foo::_bar; }
    void goToBaz() { _setFct(&foo::_baz); }
    void run() { (this->*_memberFctPtr)(true); }
};

int main()
{
    foo f;
    f.run();        // barbarbar
    f.goToBaz();
    f.run();        // bazbazbaz
}

That was it! But howcome do you need to pass member function references? when you pass normal function names as arguments, you normally do not need to use the &.. I believe because function names by themselves are pointers to the fct, a bit like array names by themselves? I guess this isn't true for class member functions? Their names are not actual pointers to the function?
That's not the "reference" operator but the "address of" operator (same symbol, different context).
Still, good question, and I'm not sure why it's needed.
Hopefully someone else will let us both know. :-)
https://en.cppreference.com/w/cpp/language/pointer states that:
* A pointer to non-static member function f which is a member of class C can be initialized with the expression &C::f exactly.
* A pointer to function can be initialized with an address of a non-member function or a static member function. Because of the function-to-pointer implicit conversion, the address-of operator is optional.
1
2
3
void f(int);
void (*p1)(int) = &f;
void (*p2)(int) = f; // same as &f 


https://isocpp.org/wiki/faq/pointers-to-members states that:
* The type of “pointer-to-member-function” is different from “pointer-to-function”
* Member functions have an implicit parameter which points to the object (the this pointer inside the member function).

I presume that implicit cast for member functions is not trivial and hence not there.
It'd like to add one thing ... be kind to yourself, use type aliases to keep the code clean.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class foo
{
    using BoolMemberPtr = void (foo::*)(bool);

    BoolMemberPtr _memberFctPtr;
    void _setFct(BoolMemberPtr value) {
        _memberFctPtr = value;
    }
    void _bar(bool) {
    }

public:
    foo() : _memberFctPtr(&foo::_bar) {
    }
    void goToBar() {
        _setFct(&foo::_bar);
    }
    void run() {
        (this->*_memberFctPtr)(true);
    }
};

int main() {
    foo f;
    f.goToBar();
    f.run();
}
Last edited on
> I believe because function names by themselves are pointers to the fct, a bit like array names by themselves?

The names themselves are not pointers to start with; but there are implicit conversions
from function to pointer to function and from array to pointer to its first element.


> I guess this isn't true for class member functions?

The standard explains it this way:
An lvalue of function type T can be converted to a prvalue of type “pointer to T”. The result is a pointer to the function.

Note: This conversion never applies to non-static member functions because an lvalue that refers to a non-static member function cannot be obtained.

https://eel.is/c++draft/conv.func#1
Topic archived. No new replies allowed.