2

In my class, If I want to point to a member of class,

struct S
{
     static int get();
     int do_something();
     int x;
};

I do,

int (*p)() = S::get;

Unfortunately this doesn't for non-static member

int (*p)() = S::do_something; // error

Since, a static member function is an ordinary function, and from the quote I came around below states that a non-static member function is also a ordinary function so why wouldn't it work? what does it mean?

(9.2/10) [Note: the type of a nonstatic member function is an ordinary function type, and the type of a nonstatic data member is an ordinary object type. There are no special member function types or data member types. ]

user103214
  • 3,478
  • 6
  • 26
  • 37
  • 1
    This is answered here: http://stackoverflow.com/questions/439540/function-pointer-to-class-member-function-problems – Teemu Ikonen Nov 26 '11 at 10:59
  • 1
    A must read to understand the concept : [Pointers to member functions](http://www.parashift.com/c++-faq-lite/pointers-to-members.html) – Mr.Anubis Nov 26 '11 at 11:04

3 Answers3

5

Non-static member functions are not ordinary functions. You cannot form free pointers to them.

The only permissible way to refer to a non-static member function is through a pair of an instance pointer/reference and a pointer-to-member-function:

S * p = &theobject;
int (S::*ptmf)() = &S::do_something;

return (p->*ptmf)();

Unlike member objects (to which you can very well form a free pointer, e.g. &theobject.x), member functions are more complicated, because you need to account for virtual functions: If S is a polymorphic base class and p is a pointer-to-base and do_something() is virtual, then the above example should perform the correct type of dispatch. A simple free function pointer cannot do this.

(Moreover, the standard does not specify how each underlying implementation of member functions is implemented, so this detail is never exposed to the user. Typically it'll be something like int S_mangled_name_do_something(S *);, but that's not specified.)

Here are some related answers of mine on the subject: #1, #2.

Community
  • 1
  • 1
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • Can you refer to non-static member **variables** in a similar fashion as pointers? – Snackoverflow Oct 26 '18 at 15:49
  • 1
    @anddero: Yes, pointers-to-member can also point to data members. For example, given `struct X { int a; };` you can form `int X::*p = &X::a;`. ([Demo](https://wandbox.org/permlink/CnR9cKdo9EpPx67G).) – Kerrek SB Oct 26 '18 at 19:56
2

The type of the function is ordinary, not the type of the function-pointer. A pointer to a non-static member-function has to be declared like this:

typedef int (S::*p)() ptr_to_member_of_s;
Björn Pollex
  • 75,346
  • 28
  • 201
  • 283
0
int (S::*p)() = S::do_something;

a non-static member function is an ordinary function except that there is an invisible parameter this.

BruceAdi
  • 1,949
  • 1
  • 11
  • 8
  • The invisible parameter is only the tip of the iceberg, though. Virtual dispatch is a far more serious design issue. – Kerrek SB Nov 26 '11 at 11:14
  • @KerrekSB Agreed. For virtual functions, we could use std::function with Lambda expression `Base* p = &theObject; std::function func = [&p]()->int{ return p->doSomething(); };` – BruceAdi Nov 26 '11 at 12:09
  • 1
    No no no -- `(p->*ptfm)()` already does take care of the correct dispatch. My argument was that a member function is more than a free function with a hidden argument. – Kerrek SB Nov 26 '11 at 12:12