2012-08-11 31 views
6

क्या यह वैध सी ++ है (नवीनतम मानक पर विचार)? मुझे उबंटू 12.04 पर निकट-शीर्ष-पेड़ क्लैंग/libC++ के साथ संकलन त्रुटियां मिल रही हैं। यदि यह मान्य होना चाहिए, तो मैं त्रुटि संदेश और इस तरह के clang-dev सूची को मेल करूंगा।unordered_set <context_wrapper <Ty>> मान्य है?

#include <functional> 
#include <unordered_set> 

struct X 
{ 
    int i; 
}; 

void f() 
{ 
    std::unordered_set<std::reference_wrapper<X>> setOfReferencesToX; 

    // Do stuff with setOfReferencesToX 
} 

** एक तरफ, मैं योग्यता प्राप्त करने के थक गया हूं कि प्रश्न/उत्तर नवीनतम मानक के लिए विशिष्ट है। क्या सी ++ समुदाय पूरी तरह से हो सकता है, कृपया उन चीजों को अर्हता प्राप्त करना शुरू करें जो पुराने मानक के लिए विशिष्ट हैं? नया मानक अब लगभग एक साल से बाहर हो गया है।

+1

+1। – Griwes

+0

"क्या सी ++ समुदाय पूरी तरह से हो सकता है, कृपया उन चीजों को अर्हता प्राप्त करना शुरू करें जो पुराने मानक के लिए विशिष्ट हैं?" नहीं। उन उपयोगकर्ताओं की बड़ी संख्या को देखते हुए जो अधिक पूर्ण C++ 11 समर्थन के साथ एक कंपाइलर में अपग्रेड करने में सक्षम नहीं हैं, केवल एक निश्चित कंपाइलर परिवार की लोकप्रियता को छोड़ दें जो केवल धीरे-धीरे इसके C++ 11 समर्थन को अपग्रेड कर रहा है, सी ++ जा रहा है कम से कम एक वर्ष के लिए सी ++ 03 का मतलब है यदि दो नहीं। और यह न भूलें कि न तो जीसीसी और न ही क्लैंग सी ++ 11 के पूर्ण अनुरूपता का दावा करता है। भविष्य वर्तमान नहीं है, और यह दिखाता है कि यह ऐसा नहीं करेगा। –

उत्तर

8

समस्या std::reference_wrapper<T> के लिए विशिष्ट नहीं है, बल्कि X के प्रकार के लिए विशिष्ट नहीं है।

समस्या यह है कि std::unordered_set की आवश्यकता है कि आप std::reference_wrapper<X> के लिए हैशिंग और समानता फ़ैक्टर को परिभाषित करें। आप हैश फ़ैक्टर को दूसरे टेम्पलेट पैरामीटर के रूप में पास कर सकते हैं।

उदाहरण के लिए, इस काम करेगा:

#include <functional> // for std::hash<int> 

struct HashX { 
    size_t operator()(const X& x) const { 
    return std::hash<int>()(x.i);  
    } 
}; 

और फिर

std::unordered_set<std::reference_wrapper<X>, HashX> setOfReferencesToX; 

एक अन्य विकल्प std::hash<X> के लिए एक विशेषज्ञता बनाने के लिए है:

namespace std { 
template <> 
struct hash<X> { 
    size_t operator()(const X& x) const { 
    return std::hash<int>()(x.i);  
    } 
}; 
} 

यह आपको स्पष्ट रूप से बचने के लिए अनुमति देता है दूसरा टेम्पलेट तर्क निर्दिष्ट करना:

std::unordered_set<std::reference_wrapper<X>> setOfReferencesToX; 

समानता तुलना के संबंध में, आप कक्षा X के लिए एक समानता ऑपरेटर प्रदान करके इसे ठीक कर सकते हैं:

struct X 
{ 
    bool operator==(const X& rhs) const { return i == rhs.i; } 
    int i; 
}; 

अन्यथा, आप अपने खुद के functor को परिभाषित करने और तीसरे टेम्पलेट तर्क के रूप में इसे पारित कर सकते हैं। अंतिम नोट के लिए

+0

'std :: हैश' का विशेषज्ञ नहीं करना थोड़ा आसान होगा? – Griwes

+0

यदि आप 'std' नेमस्पेस में सामान डालना चाहते हैं तो यह होगा। – juanchopanza

+0

मुझे नहीं लगता कि इसे "std' में सामान डालने" के रूप में योग्यता प्राप्त की जानी चाहिए, क्योंकि यह केवल विशेषज्ञता है ... – Griwes