2009-12-12 18 views
7

मेरा पूरा कोड बहुत लंबा है, लेकिन यहाँ एक टुकड़ा है कि मेरी समस्या का सार को प्रतिबिंबित करेगा है:तत्काल के बाद टेम्पलेट का विशेषज्ञता?

class BPCFGParser { 
    public: 

    ... 
    ... 

    class Edge { 
    ... 
    ... 
    }; 


    class ActiveEquivClass { 
    ... 
    ... 
    }; 

    class PassiveEquivClass { 
    ... 
    ... 
    }; 

    struct EqActiveEquivClass { 
    ... 
    ... 
    }; 

    struct EqPassiveEquivClass { 
    ... 
    ... 
    }; 



    unordered_map<ActiveEquivClass, Edge *, hash<ActiveEquivClass>, EqActiveEquivClass> discovered_active_edges; 
    unordered_map<PassiveEquivClass, Edge *, hash<PassiveEquivClass>, EqPassiveEquivClass> discovered_passive_edges; 

}; 

namespace std { 


template <> 
class hash<BPCFGParser::ActiveEquivClass> 
{ 

    public: 
     size_t operator()(const BPCFGParser::ActiveEquivClass & aec) const { 

     } 
}; 

template <> 
class hash<BPCFGParser::PassiveEquivClass> 
{ 

    public: 
     size_t operator()(const BPCFGParser::PassiveEquivClass & pec) const { 

     } 
}; 

} 

मुझे इस कोड संकलन, मैं निम्नलिखित त्रुटियाँ मिलती है:

In file included from BPCFGParser.cpp:3, 
       from experiments.cpp:2: 
BPCFGParser.h:408: error: specialization of ‘std::hash<BPCFGParser::ActiveEquivClass>’  after instantiation 
BPCFGParser.h:408: error: redefinition of ‘class     std::hash<BPCFGParser::ActiveEquivClass>’ 
/usr/include/c++/4.3/tr1_impl/functional_hash.h:44: error: previous definition of  ‘class std::hash<BPCFGParser::ActiveEquivClass>’ 
BPCFGParser.h:445: error: specialization of  ‘std::hash<BPCFGParser::PassiveEquivClass>’ after instantiation 
BPCFGParser.h:445: error: redefinition of ‘class std::hash<BPCFGParser::PassiveEquivClass>’ 
/usr/include/c++/4.3/tr1_impl/functional_hash.h:44: error: previous definition of  ‘class std::hash<BPCFGParser::PassiveEquivClass>’ 

अब मुझे इन कक्षाओं के लिए std :: हैश का विशेषज्ञ बनाना है (क्योंकि मानक std :: हैश परिभाषा में उपयोगकर्ता परिभाषित प्रकार शामिल नहीं हैं)। जब मैं कक्षा BPCFGParser की परिभाषा से पहले इन टेम्पलेट विशेषज्ञता को स्थानांतरित करता हूं, तो मुझे विभिन्न प्रकार की विभिन्न चीजों के लिए कई त्रुटियां मिलती हैं, और कहीं (http://www.parashift.com/c++-faq-lite/misc-technical-issues.html) मैंने पढ़ा है कि:

जब भी आप किसी टेम्पलेट पैरामीटर के रूप में कक्षा का उपयोग करते हैं, तो घोषणा वह कक्षा पूरी होनी चाहिए और घोषित नहीं किया जाना चाहिए।

तो मैं अटक गया हूं। मैं BPCFGParser परिभाषा के बाद टेम्पलेट्स का विशेषज्ञ नहीं हो सकता, मैं BPCFGParser परिभाषा से पहले उन्हें विशेषज्ञ नहीं कर सकता, मैं यह कैसे काम कर सकता हूं?


आप BPCFGParser के अंदर एक आंतरिक वर्ग में विशेषज्ञता बढ़ने की जरूरत है। ऐसा करने से दोनों आवश्यकताओं को पूरा किया जाता है।

आप जवाब :)

hash वर्ग नाम स्थान std भीतर परिभाषित किया गया है के लिए बहुत बहुत धन्यवाद। यह मुझे गैर-नामस्थान क्षेत्र में hash के लिए टेम्पलेट्स का विशेषज्ञ बनाने की अनुमति नहीं देता है। यहां तक ​​कि निम्नलिखित:

template <> 
    class std::hash<ActiveEquivClass> { 
... 

काम नहीं किया।

In file included from BPCFGParser.cpp:3, 
       from experiments.cpp:2: 
BPCFGParser.h:225: error: expected unqualified-id before ‘namespace’ 
experiments.cpp:7: error: expected `}' at end of input 
BPCFGParser.h:222: error: expected unqualified-id at end of input 

एक जवाब velocityreviews में दिए गए में, किसी का दावा है कि नामस्थान कक्षाओं में परिभाषित नहीं किया जा सकता: जब मैं namespace std {} साथ विशेषज्ञताओं लगा, हालांकि, यह अजीब त्रुटि देता है। तो मैं अभी भी अटक गया हूँ।

उत्तर

5

आपको विशेषज्ञता को बीपीसीएफजीपीएसर के अंदर एक आंतरिक कक्षा में स्थानांतरित करने की आवश्यकता है।

class BPCFGParser { 

    class ActiveEquivClass { 
    ... 
    }; 

    template <> 
    class hash<ActiveEquivClass> { 
    public: 
     size_t operator()(const BPCFGParser::ActiveEquivClass & aec) const { 
     } 
    }; 
    ... 
    unordered_map<ActiveEquivClass, Edge *, hash<ActiveEquivClass>, EqActiveEquivClass> discovered_active_edges; 

}; 
+0

उत्तर के लिए बहुत बहुत धन्यवाद, लेकिन यह काम नहीं करता है। स्पष्टीकरण के लिए नीचे देखें। –

1

हैश < ले जाने का प्रयास> टेम्पलेट: तो दोनों आवश्यकताओं

  1. विशेषज्ञता विशेषज्ञता

उदाहरण के उपयोग से पहले ActiveEquivClass

  • की पूरी परिभाषा के बाद है पूरा करती है कर बीपीसीएफजीपीएसर्स कक्षा घोषणा से पहले विशेषज्ञता कोड। त्रुटि का अर्थ है कि हैश का विस्तार std :: हैश पर आधारित है जिसे /usr/include/c++/4.3/tr1_impl/functional_hash.h पर परिभाषित किया गया है; तो तत्कालता से पहले आपकी विशेषज्ञता का उपयोग नहीं किया जाता है। आदर्श रूप से, टेम्पलेट का विस्तार होने से पहले आपके विशेषज्ञता कोड को कंपाइलर के लिए उपलब्ध कराया जाना चाहिए।

  • 0

    जब भी आप एक टेम्पलेट पैरामीटर के रूप में एक वर्ग का उपयोग करें, की घोषणा उस वर्ग पूरा होना चाहिए और केवल आगे घोषित नहीं किया।

    यह वास्तव में सच नहीं है। टेम्पलेट पैरामीटर को पूर्ण प्रकार होने की सीमाएं आम तौर पर टेम्पलेट सामग्री पर निर्भर होती हैं; लेकिन एक अपूर्ण प्रकार के साथ टेम्पलेट को तत्काल करना गैरकानूनी नहीं है जब तक कि टेम्पलेट में अपूर्ण प्रकार के साथ गैरकानूनी कोड न हो।

    आपकी समस्या दृष्टिकोण करने का एकमात्र तरीका कक्षा से पहले विशेषज्ञता परिभाषित करने के लिए, लेकिन कक्षा के बाद वास्तविक सदस्य समारोह operator()परिभाषित करने के लिए है। यही है,

    template <> 
    class std::hash<BPCFGParser::ActiveEquivClass> 
    { 
    public: 
        size_t operator()(const BPCFGParser::ActiveEquivClass & aec) const; 
    }; 
    
    // definition of BPCFGParser 
    
    template<> std::size_t std::hash<BPCFGParser::ActiveEquivClass>::operator()(const BPCFGParser::ActiveEquivClass & aec) const { 
    } 
    

    इसका मतलब यह भी है कि, कोई नेस्टेड क्लास नहीं है, क्योंकि आप नेस्टेड क्लास घोषित नहीं कर सकते हैं।

    0

    मैं बिल्कुल एक ही समस्या है और अंत में एक समाधान के उपयोगकर्ता परिभाषित हैश functor समाधान के साथ आते हैं, नीचे देखें:

    class Outer 
    { 
        // TC++PL, 4e, 19.4.1 : A friend must be previously declared in an enclosing scope or 
        // defined in the non-class scope immediately enclosing the class that is declaring it to be a friend. 
        struct Hash_inner; 
    
        class Inner 
        { 
         int i; 
         friend struct Hash_inner; 
        }; 
    
        struct Hash_inner 
        { 
         size_t operator()(const Inner& in) const 
         { return std::hash<int>()(in.i); } 
        }; 
    
        std::unordered_map<Inner, int, Hash_inner> um; 
    }; 
    

    और मैं stil सोच रहा हूँ वहाँ एक std :: हैश विशेषज्ञता पहुंच दी गई है कि क्या । क्या कोई इसे समझ सकता है?

    0

    मुझे पता है कि यह सवाल काफी पुराना है, लेकिन मैं अभी भी एक ही समस्या में आया हूं और मैंने सोचा कि मैं अपने निष्कर्षों की रिपोर्ट करूंगा।

    त्रुटि संदेश:

    In file included from BPCFGParser.cpp:3, 
          from experiments.cpp:2: 
    BPCFGParser.h:408: error: specialization of ‘std::hash<BPCFGParser::ActiveEquivClass>’  after instantiation 
    BPCFGParser.h:408: error: redefinition of ‘class     std::hash<BPCFGParser::ActiveEquivClass>’ 
    /usr/include/c++/4.3/tr1_impl/functional_hash.h:44: error: previous definition of  ‘class std::hash<BPCFGParser::ActiveEquivClass>’ 
    BPCFGParser.h:445: error: specialization of  ‘std::hash<BPCFGParser::PassiveEquivClass>’ after instantiation 
    BPCFGParser.h:445: error: redefinition of ‘class std::hash<BPCFGParser::PassiveEquivClass>’ 
    /usr/include/c++/4.3/tr1_impl/functional_hash.h:44: error: previous definition of  ‘class std::hash<BPCFGParser::PassiveEquivClass>’ 
    

    अपनी कक्षाओं के बारे में बिल्कुल भी शिकायत नहीं कर रहा है, यह कह रहा है कि आप विशेषज्ञ नहीं कर सकते std :: हैश क्योंकि या तो std :: हैश या में से एक के लिए सामान्य टेम्प्लेट मौजूदा विशेषज्ञता का पहले से ही उपयोग किया जा चुका है - यानी किसी ने इस बिंदु के बीच इसका उपयोग किया है कि इसे परिभाषित किया गया था और वह बिंदु जहां आप इसे विशेषज्ञता देने का प्रयास कर रहे हैं।

    this document के "विस्तार से" खंड में इस का वर्णन कुछ पाठ नहीं है: कि कारण होगा अंतर्निहित इन्स्टेन्शियशन

    मेरे मामले में

    विशेषज्ञता पहले उपयोग करने से पहले घोषित किया जाना चाहिए, समस्या मेरे विशेषज्ञता कोड के साथ नहीं थी, समस्या इसकी स्थिति के साथ थी। एक बार std :: हैश का उपयोग किया गया है, तो आप इसे और अधिक विशेषज्ञ नहीं कर सकते हैं।

    मुझे पता चला कि अगर मैंने <unordered_map> सहित तुरंत अपना विशेषज्ञता कोड स्थानांतरित किया, तो यह ठीक काम करता था।

    पिल्ला विशेषज्ञता कार्यान्वयन से आप घोषणाओं बहुत <unordered_map> के शामिल किए जाने के करीब ले जाने के लिए अनुमति देता है की घोषणा को अलग करने से सुझाव, कार्यान्वयन बाद में आ सकते हैं जहाँ भी यह सुविधाजनक है (के बाद BPCFGParser पूरी तरह से परिभाषित किया गया है अपने मामला)।

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