Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling the function pointed by a Pointer-to-Member-Function from within a struct

I have a class Test with a peculiar data structure. A member of class Test is a std::map where the key is a std::string and the mapped value is a struct defined as follows:

typedef struct {
  void (Test::*f) (void) const;
} pmf_t;

Initialization of the map is OK. The problem is when I am trying to call the function pointed. I made up a toy example reproducing the problem. Here it is:

#include <iostream>
#include <map>

using namespace std;

class Test;
typedef void (Test::*F) (void) const;
typedef struct {
  F f;
} pmf_t;


class Test
{
public:
  Test () {
    pmf_t pmf = {
      &Test::Func
    };
    m["key"] = pmf;
  }
  void Func (void) const {
    cout << "test" << endl;
  }
  void CallFunc (void) {
    std::map<std::string, pmf_t>::iterator it = m.begin ();
    ((*it).second.*f) (); // offending line
  }

  std::map<std::string, pmf_t> m;
};


int main ()
{

  Test t;
  t.CallFunc ();

  return 0;
}

Thanks in advance, Jir

like image 858
Jir Avatar asked Dec 21 '22 10:12

Jir


2 Answers

The name of the pmf_t type is f, so the first change is to remove the * to get second.f. That gives you a pointer-to-member value. To use a pointer-to-member, you need an instance. The only one you have available of the correct type is this, so use it with the ->* operator:

(this->*it->second.f)();

You need parentheses around the whole thing, or else the compiler thinks you're trying to call it->second.f() (which isn't allowed) and then applying the result to ->*.

like image 194
Rob Kennedy Avatar answered Dec 24 '22 00:12

Rob Kennedy


The offending line is trying to call a member function without any object to call it on. If the intention is to call it for the this object, I believe the call should look like

( this->* ((*it).second.f) )(); 

Where this->* is the syntax for dereferencing a pointer-to-member for the current object. ((*it).second.f) is the pointer retrieved from the map, and () is the call operator for actually calling the function.

This is perhaps good as an exercise, but otherwise of limited use.

like image 32
Bo Persson Avatar answered Dec 24 '22 02:12

Bo Persson