Question

I've got a namespace MyNamespace containing a class MyClass with many static public members functions.

What I need to do, is to build, inside the namespace, a map containing a pointer on every public members functions of the class Here the code:

    #include <iostream>
    #include <map>

    namespace MyNamespace {
      class MyClass;

      typedef bool (*fctPtr)(void);
      typedef std::map<std::string, fctPtr> fctMap;
    };

    class MyNamespace::MyClass {

      public:
        static bool func1(void) { return true; };
        static bool func2(void) { return true; };
        static bool func3(void) { return true; };
        static bool func4(void) { return true; };

    };

    MyNamespace::fctMap MyFctMap;


    void execFct() {
      MyNamespace::MyClass obj;
      MyNamespace::fctPtr fctMemb;

      fctMemb = MyFctMap["func1"];
      (obj.*fctMemb)();
    }


    int main() {
      MyFctMap["func1"] = &MyNamespace::MyClass::func1;
      MyFctMap["func2"] = &MyNamespace::MyClass::func2;
      MyFctMap["func3"] = &MyNamespace::MyClass::func3;
      MyFctMap["func4"] = &MyNamespace::MyClass::func4;

      execFct();
    }

And what the compiler says:

    % clang++ draft.cc
    draft.cc:29:7: error: right hand operand to .* has non pointer-to-member type
          'MyNamespace::fctPtr' (aka 'bool (*)()')
      (obj.*fctMemb)();
          ^ ~~~~~~~
    1 error generated.

I don't understand why I got this error neither what to do to resolve the problem. Idea?

Edit: I'm using c++98 and no boost.

Working with a typedef bool (MyClass::*fctPtr)(void) drives me to this kind od error, at map assignment time.

 error: assigning to 'mapped_type' (aka 'bool (MyNamespace::MyClass::*)()') from
      incompatible type 'bool (*)()'
  MyFctMap["func1"] = &MyNamespace::MyClass::func1;
                    ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Was it helpful?

Solution

Since the functions you are referencing are static, you don't need the obj class reference. Simply call fctMemb();. You might also consider if you need these functions mapped in such a way, oftentimes you don't need that dynamic aspect to function references in C++ and instead should be using templates.

OTHER TIPS

A pointer to a function is not the same as a pointer to a member function. The important thing to remember is that all (non-static) member function actually have a hidden first argument which is what becomes the this pointer. Therefore a function pointer and a member function pointer can't ever be compatible.

However, you should look into std::function and std::bind:

namespace NyNamespace
{
    typedef std::function<bool()> fctPtr;
    ...
}

MyNamespace::MyClass myObject;
MyFctMap["func1"] = std::bind(&MyNamespace::MyClass::func1, myObject);

The idea is fctMemb(); :-)
fctPtr, as the compiler says, is not a pointer to member type...

Static member functions are not like normal member functions. They have access to class private and protected members, but they are not tied to object instances and thus can't access this pointer nor any non-static members.

Their type is that of normal function pointers and they can't be bound to member function pointers (and normal function pointers is what you have in your code).

You call them like normal functions:

fctMemb();

Btw, the sytax to form member function pointers is different:

struct Foo {
    void f() {}
};

void (Foo::* mem_fun_ptr)() = &Foo::f;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top