2017-08-22 5 views
9

सदस्य फ़ंक्शन पॉइंटर के लिए int का नक्शा बनाने और इसे कन्स्ट्रक्टर प्रारंभकर्ता के अंदर प्रारंभ करने का प्रयास कर रहा है। इस तरह:कन्स्ट्रक्टर प्रारंभकर्ता के अंदर मानचित्र की प्रारंभिक सूची का उपयोग करके

class X 
{ 
    using STATEFUNC = void(X::*)(int); 
public: 
    X() : m{ { 1, &setState1 } } {} 

    void setState1(int x) { cout << "state1" << endl; } 

    void setState2(int x) { cout << "state2" << endl; } 


    std::map<int, STATEFUNC> m; 
}; 

मैं कहूंगा कि यह सही है, लेकिन दृश्य स्टूडियो 2017 का कहना है:

Error C2664 'std::map,std::allocator>>::map(std::initializer_list>)': cannot convert argument 1 from 'initializer list' to 'std::initializer_list>'

Error C2276 '&': illegal operation on bound member function expression

जब आप सदस्य समारोह से ऑपरेटर की पता हटाने के पहले त्रुटि संदेश ही रहता है लेकिन के बाद दूसरे स्थान परिवर्तन:

Error C3867 'X::setState1': non-standard syntax; use '&' to create a pointer to member

कैसे आप एक निर्माता प्रारंभकर्ता सूची के अंदर सदस्य समारोह सूचक को पूर्णांक का एक नक्शा प्रारंभ करते हैं?

+3

दिलचस्प। निश्चित नहीं है कि क्यों इसे यहां कक्षा का नाम चाहिए। उम्मीद है कि किसी को पता चलेगा कि क्यों एक्स(): एम {{1, और एक्स :: सेटस्टेट 1}} {} 'काम करता है लेकिन 'एक्स(): एम {{1, और सेटस्टेट 1}} {}' – NathanOliver

+1

' पहचानकर्ता 'नहीं कर सकता किसी सदस्य फ़ंक्शन का पता लेने के लिए कभी भी उपयोग न करें (या तो स्पष्ट रूप से '&' या क्षय के साथ); आपको हमेशा एक योग्य-आईडी –

उत्तर

9

X() : m{ { 1, &X::setState1 } } {} 

केवल &setState1 मैं बजना ++ से त्रुटि निम्न संदेश त्रुटि

error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say ‘&X::setState1’ [-fpermissive]

का उपयोग करना, जी ++ से, के साथ प्रयास करें बस

error: must explicitly qualify name of member function when taking its address

है - संपादित करें -

मेरा उत्तर बताता है कि समस्या को कैसे हल किया जाए।

को समझने के लिए क्यों &X::setState1 काम करता है और &setState1 नहीं, तो कृपया कथाकार के जवाब (+1)

14

देखता answermax66 से ठीक है। क्यों यह ठीक है: कारण यह है कि आपका कोड किसी सदस्य को पॉइंटर नहीं बनाता है। n4659 के शब्दों में (पिछले सी ++ 17 मसौदा है, लेकिन पिछले मानक संशोधन एक ही कहते हैं):

[expr.unary.op/4]

A pointer to member is only formed when an explicit & is used and its operand is a qualified-id not enclosed in parentheses. [ Note: That is, the expression &(qualified-id), where the qualified-id is enclosed in parentheses, does not form an expression of type “pointer to member”. Neither does qualified-id, because there is no implicit conversion from a qualified-id for a non-static member function to the type “pointer to member function” as there is from an lvalue of function type to the type “pointer to function” ([conv.func]). Nor is &unqualified-id a pointer to member, even within the scope of the unqualified-id's class.  — end note ]

X::setState1 एक योग्य आईडी है, लेकिन setState1 नहीं है।

+0

का उपयोग करना होगा, मुझे लगता है कि इस भेद के लिए एक अच्छा कारण है। जैसे कोई '' और m'' प्रकार '' std :: map * '' की अपेक्षा करेगा, इसलिए एक अलग वाक्यविन्यास की आवश्यकता है, विशेष रूप से ''और X :: m''' 'std प्राप्त करने के लिए: : नक्शा X :: * ''। इसके बाद गैर-स्थैतिक विधियों के लिए बाद वाले वाक्यविन्यास की आवश्यकता होती है, भले ही अयोग्य आईडी के साथ वाक्यविन्यास अवैध है। –

+0

@AneneVogel - आप बहुत सही हैं। इसके अलावा, सदस्यों को पॉइंटर्स को परिभाषित करते समय, सदस्य कार्यों और डेटा सदस्यों के बीच एक भेद भी नहीं करना चाहिए। अगर हमारे पास 'टीसी :: * अपराह्न = &C::m;' है, तो घोषणा सही है कि 'टी' एक ऑब्जेक्ट प्रकार (कौन सा मैचों) है या एक कार्य उपनाम है जैसे 'टी = शून्य (शून्य) का उपयोग करना;' (और एम है इस प्रोटोटाइप के साथ एक सदस्य समारोह)। वाक्यविन्यास * verbosity के बावजूद * इस तरह से * बहुत संगत है। – StoryTeller

संबंधित मुद्दे