2012-04-04 15 views
9

इस पर विचार करें:स्पष्ट रूप से पॉइंटर्स के वेक्टर को प्रारंभ करने से रूपांतरण त्रुटि में परिणाम मिलता है?

std::vector<int*> v(1, 0); 

यह (यहां तक ​​कि अधिकतम चेतावनी स्तर में कोई चेतावनी) कुलपति ++ 10 के साथ ठीक संकलित करता है। हालांकि, यह लिनक्स पर मैक या जीसीसी पर llvm के साथ संकलित नहीं करता है, जैसे "असंगत प्रकार const int से int * को असाइन करना" जैसी त्रुटि प्रदान करना। मैं समाधान की तलाश नहीं कर रहा हूं - मुझे पता है कि दूसरा पैरामीटर अनावश्यक है या एक static_cast त्रुटि को हल करता है।

मैंने सोचा कि शून्य किसी भी सूचक प्रकार के लिए पूरी तरह से परिवर्तनीय था। क्या देता है?

int* i = 0; 
int* const& ii = 0; 
const int t = 0; 
i = t; 

मैं समझता हूँ कि वेक्टर निर्माता हस्ताक्षर एक const T& लेता है जो जब vector<int*> के लिए विस्तार किया int* const& सही हो जाता है: मैं निम्नलिखित कर सकते हैं? क्या कोई यहां बता रहा है कि क्या हो रहा है, और क्या वीसी ++ या गैर-वीसी ++ कंपाइलर सही है?

+0

'0' के बजाय' nullptr' आज़माएं। – ildjarn

+1

क्या आप इसे C++ 03 या C++ 11 प्रोग्राम के रूप में संकलित कर रहे हैं? –

+0

प्रश्न से संबंधित नहीं है, लेकिन, आप कच्चे पॉइंटर्स का उपयोग क्यों कर रहे हैं जब [बजेर्न ने कहा कि हमें उनसे बचना चाहिए] (http://channel9.msdn.com/Events/GoingNative/GoingNative-2012/Keynote-Bjarne-Stroustrup-Cpp11- अंदाज)? –

उत्तर

2

ऐसा लगता है कि जी ++ वास्तव में यहां गलत है। देखें सी ++ 98 23.1.1/9:

इस खंड में और धारा 21 में परिभाषित हर अनुक्रम के लिए:

- निर्माता टेम्पलेट एक्स (InputIterator च, InputIterator एल, स्थिरांक संभाजक & ए = आवंटक())

के समान प्रभाव होगा: X(static_cast<typename X::size_type>(f), static_cast<typename X::value_type>(l), a) यदि इनपुट इटरेटर अभिन्न प्रकार है।

ध्यान दें कि InputIterator निर्माता, जो इस मामले में अपने उदाहरण के लिए int, और इस तरह एक अभिन्न प्रकार हो जाएगा के लिए एक टेम्पलेट पैरामीटर है। जी ++ लाइब्रेरी में वास्तव में सभी मामलों को संभालने के लिए विशिष्ट कोड है जहां vector में संग्रहीत प्रकार भी अभिन्न है और वे सभी ठीक से काम करेंगे। इस मामले में, केवल इसलिए कि आपने 0 का उपयोग किया था, मानक मानक द्वारा निर्धारित static_cast होगा। मैंने कोड को संकलित करने की कोशिश की जो मानक कहता है समकक्ष होना चाहिए और यह g ++ 4.5 के साथ संकलित करता है।

+0

अच्छा काम। 'std :: वेक्टर v (1, 0); 'बस ठीक है। मैंने एमएस को यहां सही होने की उम्मीद नहीं की थी। – Tabber33

+0

यह इस बात पर निर्भर करता है कि कार्यान्वयन पर विचार किया गया है [लाइब्रेरी अंक # 438] (http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#438) जो कहता है कि यह ' टी काम नहीं सुझाया गया समाधान 'एक्स (static_cast (f), l, a) है जो 'टैबबर की विफलता से मेल खाता है। इसके बजाय सी ++ 11 का पालन किया [दोष रिपोर्ट # 1234] (http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#1234), फिर से, एक अलग परिणाम। –

2

std::vector इस हस्ताक्षर

template <class InputIterator> 
vector(InputIterator first, InputIterator last, 
     const Allocator& = Allocator()); 

जो, अगर संकलक काट लेता है InputIteratorint (!) अपने मानकों 0 और 1 से के रूप में, एक अच्छा फिट हो जाएगा, लेकिन हम क्या चाहते हैं नहीं कर के साथ एक बुरा निर्माता है।

मुझे विश्वास है कि सी ++ 11 को संकलक को यह पता लगाने के लिए कठिन प्रयास करने की आवश्यकता है कि पैरामीटर वास्तव में इटरेटर हो या नहीं। सी ++ 03 में वे शायद आपकी समस्या के कारण size_type(1) और int(0) के रूप में समाप्त हो जाएंगे।

पूर्णांक अक्षर 0 एक शून्य सूचक में परिवर्तनीय है, लेकिन int मान 0 के साथ नहीं है!

+0

धन्यवाद। आप सही हैं - त्रुटियों को और अधिक बारीकी से देखते हुए, अब मैं देखता हूं कि टेम्पलेट कन्स्ट्रक्टर का त्वरण त्रुटि पेड़ की जड़ पर था। मुझे केवल आश्चर्य है कि वीसी ++ (यहां तक ​​कि प्री-सी ++ 11 सपोर्ट) यहां इच्छित कंस्ट्रक्टर को कॉल करने के लिए अतिरिक्त "परेशानी" पर जाता है, और ऐसा करने के लिए भाषा नियमों का उल्लंघन करता है (आखिरकार, टेम्पलेटलाइज्ड कन्स्ट्रक्टर एक बेहतर मैच है)? – Tabber33

+0

@ बो पर्सन अगर मैं 23.1.1/9 सही ढंग से पढ़ रहा हूं, तो यह सही जवाब नहीं है: g ++ वास्तव में एक विशेष मामला चूक गया। –

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