指向命名空间内的成员函数的指针

pointer to member function inside namespace

本文关键字:成员 指针 函数 命名空间      更新时间:2023-10-16

>我有一个命名空间MyNamespace,其中包含一个具有许多静态公共成员函数的类MyClass

我需要做的是在命名空间内构建一个map,其中包含该类的每个公共成员函数上的指针这里的代码:

    #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();
    }

编译器说:

    % 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.

我不明白为什么我得到这个错误,也不明白该怎么做才能解决问题。想法?

编辑:我正在使用c ++ 98,没有提升。

在地图分配时,使用typedef bool (MyClass::*fctPtr)(void)会使我遇到这种 od 错误。

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

由于引用的函数是静态的,因此不需要obj类引用。只需致电fctMemb();.您还可以考虑是否需要以这种方式映射这些函数,通常您不需要该动态方面来C++中的函数引用,而应该使用模板。

指向函数的指针与指向成员函数的指针不同。要记住的重要一点是,所有(非静态)成员函数实际上都有一个隐藏的第一个参数,该参数成为this指针。因此,函数指针和成员函数指针永远不能兼容。

但是,您应该研究std::functionstd::bind

namespace NyNamespace
{
    typedef std::function<bool()> fctPtr;
    ...
}
MyNamespace::MyClass myObject;
MyFctMap["func1"] = std::bind(&MyNamespace::MyClass::func1, myObject);

这个想法fctMemb(); :-)
正如编译器所说,fctPtr不是指向成员类型的指针......

静态成员函数与普通成员函数不同。它们有权访问类私有成员和受保护成员,但它们不绑定到对象实例,因此无法访问指针this也无法访问任何非静态成员。

它们的类型是普通函数指针的类型,它们不能绑定到成员函数指针(普通函数指针是代码中的内容)。

您可以像普通函数一样调用它们:

fctMemb();

顺便说一句,形成成员函数指针的 sytax 是不同的:

struct Foo {
    void f() {}
};
void (Foo::* mem_fun_ptr)() = &Foo::f;