2014-03-01 3 views
2

많은 정적 공용 멤버 함수가있는 MyClass 클래스를 포함하는 MyNamespace 네임 스페이스가 있습니다. 컴파일러는 말한다네임 스페이스 내부의 멤버 함수에 대한 포인터

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

그리고 무엇 :

내가해야 할 일은는 여기에 클래스 코드의 모든 public 멤버 함수에 대한 포인터를 포함하는 map, 네임 스페이스 안에 구축하는 것입니다

% 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

가 네, 편집, 들으 – tbenett

답변

2

때문에, 당신은 obj 클래스 참조가 필요하지 않습니다. fctMemb();에 전화하기 만하면됩니다. 또한 이러한 방식으로 맵핑 된 함수가 필요한지 고려해보십시오. C++에서 함수 참조에 동적 측면이 필요하지 않고 템플릿을 사용해야하는 경우가 종종 있습니다.

+0

효과적으로 문제는 인스턴스와 함께 사용되는 정적 키워드에서 발생했습니다. thx mate – tbenett

0

생각은 ... 함수에 대한 포인터가 함수와 동일하지

0

컴파일러가 말한대로 fctMemb(); :-)
fctPtr는 것입니다 멤버 유형에 대한 포인터 아니다 멤버 포인터. 기억해야 할 중요한 점은 모든 (정적이 아닌) 멤버 함수는 실제로는 포인터가되는 숨겨진 첫 번째 인수를가집니다. 따라서 함수 포인터와 멤버 함수 포인터는 호환 될 수 없습니다.

그러나 std::functionstd::bind에 보일 것입니다 : 당신이 참조하는 기능이 정적

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

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

들으은,하지만 허용되지 않아 C++ 11을 사용하고 싶지만 생각이납니다. – tbenett

+0

@ n0t 부스트는 어떨까요? 거기에도 변종이 있습니다. –

+0

동일, 부스트 없음;) – tbenett

0

정적 멤버 함수는 일반 멤버 함수와 다릅니다. 이들은 private 및 protected 클래스 클래스에 액세스 할 수 있지만 객체 인스턴스에 연결되어 있지 않으므로 this 포인터 또는 비 정적 멤버에 액세스 할 수 없습니다.

그 유형은 일반 함수 포인터의 유형이며 멤버 함수 포인터에 바인딩 될 수 없습니다 (일반 함수 포인터는 코드에있는 것입니다).

당신은 정상적인 기능처럼 전화 :

fctMemb(); 

, BTW 멤버 함수 포인터를 형성하는 sytax이 다른 :

이 이
struct Foo { 
    void f() {} 
}; 

void (Foo::* mem_fun_ptr)() = &Foo::f; 
이 이
관련 문제