【问题标题】:pointer to member function inside namespace指向命名空间内的成员函数的指针
【发布时间】:2014-03-01 19:44:51
【问题描述】:

我有一个命名空间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) 让我在地图分配时遇到这种奇怪的错误。

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

【问题讨论】:

    标签: c++ pointers namespaces function-call


    【解决方案1】:

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

    【讨论】:

    • 实际上,问题来自静态关键字,与实例一起使用,thx mate
    【解决方案2】:

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

    但是,您应该查看std::functionstd::bind

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

    【讨论】:

    • 谢谢,但我不允许使用 c++11,但我明白了。
    • @n0t Boost 怎么样?那里也有变种。
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

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

      你像普通函数一样调用它们:

      fctMemb();
      

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多