命名空间中的成员函数指针

时间:2014-03-01 19:44:52

标签: c++ pointers namespaces function-call

我有一个名称空间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;
                    ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

4 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:1)

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

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

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

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

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

你称之为正常功能:

fctMemb();

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

struct Foo {
    void f() {}
};

void (Foo::* mem_fun_ptr)() = &Foo::f;