C++ typedef member function signature syntax

32,529

Solution 1

For questions regarding the awkward function pointer syntax, I personally use a cheat-sheet: The Function Pointers Tutorial (downloadable here, thanks to Vector for pointing it out).

The signature of a member function, however, is a bit different from the signature of a regular function, as you experienced.

As you probably know, a member function has a hidden parameter, this, whose type need be specified.

// C++11 and above.
using Member = int (Foo::*)(int, int);

// C++03 and below.
typedef int (Foo::*Member)(int, int);

does let you specify that the first element passed to the function will be a Foo* (and thus your method really takes 3 arguments, when you think of it, not just 2.

However there is another reason too, for forcing you to specify the type.

A function pointer might refer to a virtual function, in which case things can get quite complicated. Therefore, the very size of the in-memory representation changes depending on the type of function. Indeed, on Visual Studio, a function pointer's size might vary between 1 and 4 times the size of a regular pointer. This depends on whether the function is virtual, notably.

Therefore, the class the function refers to is part of the signature, and there is no work-around.

Solution 2

You can factor out the target class in modern C++ (post 11) by utilizing the 'typedefing' qualities of template aliases. What you need would look like like:

template<typename T>
using memberf_pointer = int (T::*)(int, int); 

Yet at the point of declaration, a pointer to member function utilizing this syntax would need to specify the target class:

// D is a member function taking (int, int) and returning int
memberf_pointer<foo> mp = &foo::D; 

Solution 3

The reason it doesn't work with your current syntax is that operator precedence dictates that you're referring to a function named foo::memberf_signature, not any sort of type.

I don't know for sure if you can do this or not, but I couldn't come up with any combination of parenthese that induced the code to compile with g++ 4.2.

Solution 4

It works for me:

#include <iostream>

class foo
  {
public:
  int g (int x, int y) { return x + y ; }
  } ;

typedef int (foo::*memberf_pointer)(int, int);

int main()
  {
  foo f ;
  memberf_pointer mp = &foo::g ;
  std::cout << (f.*mp) (5, 8) << std::endl ;
  }
Share:
32,529
0xbadf00d
Author by

0xbadf00d

Updated on April 01, 2021

Comments

  • 0xbadf00d
    0xbadf00d about 3 years

    I want to declare type definition for a member function signature. Global function typedefs look like this:

    typedef int (function_signature)(int, int);
    typedef int (*function_pointer) (int, int);
    

    But I'm not able to the same thing for a member function:

    typedef int (foo::memberf_signature)(int, int);   // memberf_pointer is not a member of foo
    typedef int (foo::*memberf_pointer)(int, int);
    

    It sounds logically to me, because foo:: is the syntax to access a member in the class foo.

    How can I typedef just the signature?