2012-11-18 16 views
5

निम्नलिखित के तत्वों के लिए बुरा है:कॉन्स्ट-शुद्धता एसटीडी कंटेनर

vector<const int> vec; 

समस्या यह है कि टेम्पलेट प्रकार आबंटित होने की जरूरत है है। निम्नलिखित कोड को संकलित करता है [संपादित करें: दृश्य स्टूडियो 2010 में], ऊपर के साथ एक समस्या का प्रदर्शन:

vector<const int> vec; 
vec.push_back(6); 
vec[0] += 4; 

अधिक जटिल प्रकार के साथ, यह एक गंभीर समस्या हो सकती है।

मेरा पहला सवाल यह है कि इस व्यवहार का कोई कारण है या नहीं। ऐसा लगता है जैसे कॉन्स कंटेनर बनाना संभव हो सकता है जो उपरोक्त और गैर-कॉन्स कंटेनरों को अस्वीकार करते हैं जो इसे अनुमति देते हैं।

दूसरा, इस तरह से काम करने वाले कंटेनर बनाने का कोई तरीका है?

तीसरा, वास्तव में यहां क्या हो रहा है (उपयोगकर्ता प्रकार के साथ)? मुझे एहसास है कि यह अनिर्धारित व्यवहार है, लेकिन एसटीएल भी इसे संकलित कैसे कर रहा है?

+2

आप मानक लाइबेरे का उपयोग ऐसे तरीके से कर रहे हैं जो अपरिभाषित व्यवहार है। इसका मतलब है कि क्या होना चाहिए * पर * कोई आवश्यकता नहीं है। कुछ ऑपरेशन काम करने लगते हैं, अन्य शायद नहीं। और विभिन्न कार्यान्वयन के बीच उम्मीद की कोई स्थिरता नहीं है। –

+1

यह g ++ 4.6.3 पर संकलित नहीं करता है। –

+1

आपका कोड C++ मानक के साथ संकलित नहीं करता है। –

उत्तर

3

कारण std::vector<T const> की अनुमति नहीं है कि शुरुआत से अलग जगह पर डालने पर वेक्टर में ऑब्जेक्ट को फिर से बदलना पड़ सकता है। अब, सदस्य std::vector<T>::push_back(T const& v) धारणात्मक (संभाजक टेम्पलेट पैरामीटर बाहर छोड़ने के रूप में यह इस चर्चा के लिए अप्रासंगिक है)

template <typename T> 
void std::vector<T>::push_back(T const& v) { 
    this->insert(this->end(), v); 
} 

जो कि यह कैसे कुछ कार्यान्वयन पर कार्यान्वित किया जाता है हो रहा है के बराबर है। अब, इस ऑपरेशन को सामान्य रूप से, कुछ वस्तुओं को स्थानांतरित करने की आवश्यकता हो सकती है, और इस प्रकार, T तर्क को असाइन करने योग्य होना आवश्यक है। ऐसा लगता है कि एमएसवीसी ++ के साथ मानक लाइब्रेरी शिपिंग ऑपरेशन का प्रतिनिधित्व नहीं करता है, लेकिन push_back() में, अंतरिक्ष से बाहर होने पर सभी आवश्यक हैंडलिंग, यानी, सरणी का आकार बदलना और वस्तुओं को उचित रूप से स्थानांतरित करना करता है। यह push_back() का उपयोग करने में सक्षम होने के लिए T प्रकार की आवश्यकताएं बिल्कुल स्पष्ट नहीं हैं।

सिद्धांत रूप में, एक कंटेनर दोनों T const और बीच में एक insert() के समर्थन के संभव होगा, हालांकि: कुछ नहीं आंतरिक भंडारण, जबकि इंटरफ़ेस में एक T& उजागर T बजाय typename std::remove_const<T>::type होने की आवश्यकता है। const के बारे में थोड़ा सावधान रहना आवश्यक है जैसे operator[]() जैसे T const& का उपयोग करते हुए वापसी प्रकार के रूप में T कुछ प्रकार S const का परिणाम S const const होगा। सी ++ 2003 में यह एक त्रुटि होगी, सी ++ 2011 में मुझे लगता है कि const बस ध्वस्त हो गए हैं। सुरक्षित होने के लिए आप typename std::add_const<T>::type& का उपयोग कर सकते हैं।

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