我有一个名称空间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;
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
答案 0 :(得分:3)
由于您引用的函数是静态的,因此您不需要obj
类引用。只需致电fctMemb();
即可。您也可以考虑是否需要以这种方式映射这些函数,通常您不需要动态方面来在C ++中使用引用,而应该使用模板。
答案 1 :(得分:1)
指向函数的指针与成员指针的函数不同。要记住的重要一点是,所有(非静态)成员函数实际上都有一个隐藏的第一个参数,它就是this
指针。因此,函数指针和成员函数指针永远不能兼容。
但是,您应该查看std::function
和std::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;